TV: add a test for overlay view from TV input to CtsVerifier

- Test if bundled Live Channels app shows overlay view from 3rd-party
  TV inputs.

Bug: 18069561
Change-Id: I4033404e44e0e64da694a6c2ea8459aadc949622
diff --git a/apps/CtsVerifier/res/layout/tv_overlay.xml b/apps/CtsVerifier/res/layout/tv_overlay.xml
new file mode 100644
index 0000000..8cd5dd8
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/tv_overlay.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+         android:orientation="vertical"
+         android:layout_width="match_parent"
+         android:layout_height="match_parent">
+
+    <TextView
+            android:id="@+id/overlay_view_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="20sp"
+            android:text="@string/overlay_view_text">
+    </TextView>
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 383dcae..9ebfac7 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1343,8 +1343,13 @@
     <string name="tv_input_discover_test_verify_tune">
     Tune command must be called.
     </string>
+    <string name="tv_input_discover_test_verify_overlay_view">
+    Overlay view must be shown. Verify that there is a text view displaying \"Overlay View Dummy Text\"
+    when you tune to the \"Dummy\" channel.
+    </string>
 
     <string name="tv_launch_tv_app">Launch TV app</string>
+    <string name="overlay_view_text">Overlay View Dummy Text</string>
 
     <!-- A list of fully-qualified test classes that should not be run. -->
     <string-array name="disabled_tests" />
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
index 8c5b18c..ae0a699 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
@@ -16,18 +16,23 @@
 
 package com.android.cts.verifier.tv;
 
+import com.android.cts.verifier.R;
+
 import android.content.Context;
 import android.media.tv.TvInputService;
 import android.net.Uri;
 import android.util.Pair;
 import android.view.Surface;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.TextView;
 
 public class MockTvInputService extends TvInputService {
     private static final String TAG = "MockTvInputService";
 
     private static Object sLock = new Object();
     private static Pair<View, Runnable> sTuneCallback = null;
+    private static Pair<View, Runnable> sOverlayViewCallback = null;
 
     static void expectTune(View postTarget, Runnable successCallback) {
         synchronized (sLock) {
@@ -35,14 +40,25 @@
         }
     }
 
+    static void expectOverlayView(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sOverlayViewCallback = Pair.create(postTarget, successCallback);
+        }
+    }
+
     @Override
     public Session onCreateSession(String inputId) {
-        return new MockSessionImpl(this);
+        Session session = new MockSessionImpl(this);
+        session.setOverlayViewEnabled(true);
+        return session;
     }
 
     private static class MockSessionImpl extends Session {
+        private Context mContext;
+
         private MockSessionImpl(Context context) {
             super(context);
+            mContext = context;
         }
 
         @Override
@@ -50,6 +66,29 @@
         }
 
         @Override
+        public View onCreateOverlayView() {
+            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                    LAYOUT_INFLATER_SERVICE);
+            View view = inflater.inflate(R.layout.tv_overlay, null);
+            TextView textView = (TextView) view.findViewById(R.id.overlay_view_text);
+            textView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    Pair<View, Runnable> overlayViewCallback = null;
+                    synchronized (sLock) {
+                        overlayViewCallback = sOverlayViewCallback;
+                        sOverlayViewCallback = null;
+                    }
+                    if (overlayViewCallback != null) {
+                        overlayViewCallback.first.post(overlayViewCallback.second);
+                    }
+                }
+            });
+            return view;
+        }
+
+        @Override
         public boolean onSetSurface(Surface surface) {
             return true;
         }
@@ -68,6 +107,8 @@
             if (tuneCallback != null) {
                 tuneCallback.first.post(tuneCallback.second);
             }
+            notifyVideoAvailable();
+            notifyContentAllowed();
             return true;
         }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
index cee05e2..a627a55 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -33,6 +33,9 @@
     private View mVerifySetupItem;
     private View mTuneToChannelItem;
     private View mVerifyTuneItem;
+    private View mVerifyOverlayViewItem;
+    private boolean mTuneVerified;
+    private boolean mOverlayViewVerified;
 
     @Override
     public void onClick(View v) {
@@ -66,10 +69,21 @@
             MockTvInputService.expectTune(postTarget, new Runnable() {
                 @Override
                 public void run() {
-                    postTarget.removeCallbacks(failCallback);
                     setPassState(mTuneToChannelItem, true);
                     setPassState(mVerifyTuneItem, true);
-                    getPassButton().setEnabled(true);
+
+                    mTuneVerified = true;
+                    updatePassState(postTarget, failCallback);
+                }
+            });
+            MockTvInputService.expectOverlayView(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mVerifyOverlayViewItem, true);
+
+                    mOverlayViewVerified = true;
+                    updatePassState(postTarget, failCallback);
                 }
             });
         }
@@ -85,5 +99,14 @@
         mTuneToChannelItem = createUserItem(R.string.tv_input_discover_test_tune_to_channel,
                 R.string.tv_launch_tv_app, this);
         mVerifyTuneItem = createAutoItem(R.string.tv_input_discover_test_verify_tune);
+        mVerifyOverlayViewItem = createAutoItem(
+                R.string.tv_input_discover_test_verify_overlay_view);
+    }
+
+    private void updatePassState(View postTarget, Runnable failCallback) {
+        if (mTuneVerified && mOverlayViewVerified) {
+            postTarget.removeCallbacks(failCallback);
+            getPassButton().setEnabled(true);
+        }
     }
 }