Add TvInputInfoTest

Add TvInputInfoTest and deprecate badly outdated TvInputManagerTest.

Bug: 16831503, Bug: 16409584
Change-Id: Id1fa670859a9824ca644e0b39e961e9e65694f85
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 4fa5ba1..615e955 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -116,6 +116,7 @@
     CtsTextTestCases \
     CtsTextureViewTestCases \
     CtsThemeTestCases \
+    CtsTvTestCases \
     CtsUiAutomationTestCases \
     CtsUiRenderingTestCases \
     CtsUtilTestCases \
diff --git a/tests/tests/tv/Android.mk b/tests/tests/tv/Android.mk
index 477fe39..b45129d 100644
--- a/tests/tests/tv/Android.mk
+++ b/tests/tests/tv/Android.mk
@@ -12,10 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Temporarily disable building the TV CTS until we finalize the API.
-# See b/15419005.
-ifeq (1,0)
-
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -33,5 +29,3 @@
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
-
-endif
diff --git a/tests/tests/tv/AndroidManifest.xml b/tests/tests/tv/AndroidManifest.xml
index 553f93b..5fc5aef 100644
--- a/tests/tests/tv/AndroidManifest.xml
+++ b/tests/tests/tv/AndroidManifest.xml
@@ -17,29 +17,36 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.tv.cts">
+        package="android.media.tv.cts">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
-        <uses-library android:name="android.test.runner"/>
-        <service android:name="android.tv.cts.TvInputManagerTest$MockTvInputInternalService"
-                android:permission="android.permission.BIND_TV_INPUT">
+        <activity android:name="android.media.tv.cts.TvInputSetupActivityStub">
             <intent-filter>
-                <action android:name="android.tv.TvInputService" />
+                <action android:name="android.intent.action.MAIN" />
             </intent-filter>
-        </service>
-        <service android:name="android.tv.cts.TvInputManagerTest$MockTvInputRemoteService"
-                android:permission="android.permission.BIND_TV_INPUT"
-                android:process=":remoteTvInputForTest"
-                android:isolatedProcess="true">
+        </activity>
+
+        <activity android:name="android.media.tv.cts.TvInputSettingsActivityStub">
             <intent-filter>
-                <action android:name="android.tv.TvInputService" />
+                <action android:name="android.intent.action.MAIN" />
             </intent-filter>
+        </activity>
+
+        <service android:name="android.media.tv.cts.StubTvInputService"
+                 android:permission="android.permission.BIND_TV_INPUT"
+                 android:label="TV input stub"
+                 android:icon="@drawable/robot"
+                 android:process=":tvInputStub">
+            <intent-filter>
+                <action android:name="android.media.tv.TvInputService" />
+            </intent-filter>
+            <meta-data android:name="android.media.tv.input"
+                       android:resource="@xml/stub_tv_input_service" />
         </service>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-            android:targetPackage="android.tv.cts"
+            android:targetPackage="android.media.tv.cts"
             android:label="Tests for the TV APIs.">
         <meta-data android:name="listener"
                 android:value="com.android.cts.runner.CtsTestRunListener" />
diff --git a/tests/tests/tv/res/drawable/robot.png b/tests/tests/tv/res/drawable/robot.png
new file mode 100644
index 0000000..8a9e698
--- /dev/null
+++ b/tests/tests/tv/res/drawable/robot.png
Binary files differ
diff --git a/tests/tests/tv/res/xml/stub_tv_input_service.xml b/tests/tests/tv/res/xml/stub_tv_input_service.xml
new file mode 100644
index 0000000..8ad10cc
--- /dev/null
+++ b/tests/tests/tv/res/xml/stub_tv_input_service.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 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.
+-->
+
+<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
+    android:setupActivity="android.media.tv.cts.TvInputSetupActivityStub"
+    android:settingsActivity="android.media.tv.cts.TvInputSettingsActivityStub" />
diff --git a/tests/tests/tv/src/android/media/tv/cts/StubTvInputService.java b/tests/tests/tv/src/android/media/tv/cts/StubTvInputService.java
new file mode 100644
index 0000000..b70dc62
--- /dev/null
+++ b/tests/tests/tv/src/android/media/tv/cts/StubTvInputService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+package android.media.tv.cts;
+
+import android.content.Context;
+import android.media.tv.TvInputService;
+import android.net.Uri;
+import android.view.Surface;
+
+/**
+ * Stub implementation of (@link android.media.tv.TvInputService}.
+ */
+public class StubTvInputService extends TvInputService {
+    @Override
+    public Session onCreateSession(String inputId) {
+        return new StubSessionImpl(this);
+    }
+
+    private static class StubSessionImpl extends Session {
+        StubSessionImpl(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onRelease() {
+        }
+
+        @Override
+        public boolean onSetSurface(Surface surface) {
+            return false;
+        }
+
+        @Override
+        public void onSetStreamVolume(float volume) {
+        }
+
+        @Override
+        public boolean onTune(Uri channelUri) {
+            return false;
+        }
+
+        @Override
+        public void onSetCaptionEnabled(boolean enabled) {
+        }
+    }
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java
new file mode 100644
index 0000000..02802a7
--- /dev/null
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputInfoTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package android.media.tv.cts;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager;
+import android.media.tv.TvInputService;
+
+/**
+ * Test for {@link android.media.tv.TvInputInfo}.
+ */
+public class TvInputInfoTest extends AndroidTestCase {
+    private TvInputInfo mStubInfo;
+    private PackageManager mPackageManager;
+
+    @Override
+    public void setUp() throws Exception {
+        TvInputManager manager =
+                (TvInputManager) mContext.getSystemService(Context.TV_INPUT_SERVICE);
+        for (TvInputInfo info : manager.getTvInputList()) {
+            if (info.getServiceInfo().name.equals(
+                    StubTvInputService.class.getName())) {
+                mStubInfo = info;
+                break;
+            }
+        }
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    public void testGetIntentForSettingsActivity() throws Exception {
+        Intent intent = mStubInfo.getIntentForSettingsActivity();
+
+        assertEquals(intent.getComponent(), new ComponentName(
+                TvInputSettingsActivityStub.class.getPackage().getName(),
+                TvInputSettingsActivityStub.class.getName()));
+        String inputId = intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
+        assertEquals(mStubInfo.getId(), inputId);
+    }
+
+    public void testGetIntentForSetupActivity() throws Exception {
+        Intent intent = mStubInfo.getIntentForSetupActivity();
+
+        assertEquals(intent.getComponent(), new ComponentName(
+                TvInputSetupActivityStub.class.getPackage().getName(),
+                TvInputSetupActivityStub.class.getName()));
+        String inputId = intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
+        assertEquals(mStubInfo.getId(), inputId);
+    }
+
+    public void testTunerHasNoParentId() throws Exception {
+        assertNull(mStubInfo.getParentId());
+    }
+
+    public void testGetTypeForTuner() throws Exception {
+        assertEquals(mStubInfo.getType(), TvInputInfo.TYPE_TUNER);
+    }
+
+    public void testTunerIsNotPassthroughInput() throws Exception {
+        assertFalse(mStubInfo.isPassthroughInputType());
+    }
+
+    public void testLoadIcon() throws Exception {
+        assertEquals(mStubInfo.loadIcon(mContext).getConstantState(),
+                mStubInfo.getServiceInfo().loadIcon(mPackageManager).getConstantState());
+    }
+
+    public void testLoadLabel() throws Exception {
+        assertEquals(mStubInfo.loadLabel(mContext),
+                mStubInfo.getServiceInfo().loadLabel(mPackageManager));
+    }
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputSettingsActivityStub.java b/tests/tests/tv/src/android/media/tv/cts/TvInputSettingsActivityStub.java
new file mode 100644
index 0000000..00dfd8b
--- /dev/null
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputSettingsActivityStub.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+package android.media.tv.cts;
+
+import android.preference.PreferenceActivity;
+
+public class TvInputSettingsActivityStub extends PreferenceActivity {
+
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputSetupActivityStub.java b/tests/tests/tv/src/android/media/tv/cts/TvInputSetupActivityStub.java
new file mode 100644
index 0000000..2e5467b
--- /dev/null
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputSetupActivityStub.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+package android.media.tv.cts;
+
+import android.preference.PreferenceActivity;
+
+public class TvInputSetupActivityStub extends PreferenceActivity {
+
+}
diff --git a/tests/tests/tv/src/android/tv/cts/TvInputManagerTest.java b/tests/tests/tv/src/android/tv/cts/TvInputManagerTest.java
deleted file mode 100644
index 0b9378f..0000000
--- a/tests/tests/tv/src/android/tv/cts/TvInputManagerTest.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.
- */
-
-package android.media.tv.cts;
-
-import android.content.ComponentName;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.text.TextUtils;
-import android.media.tv.TvContract;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvInputManager.Session;
-import android.media.tv.TvInputManager.SessionCallback;
-import android.media.tv.TvInputManager.TvInputListener;
-import android.media.tv.TvInputService;
-import android.media.tv.TvInputService.TvInputSessionImpl;
-import android.util.Log;
-import android.view.Surface;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test for {@link android.media.tv.TvInputManager}.
- */
-public class TvInputManagerTest extends AndroidTestCase {
-    private static final String TAG = "TvInputManagerTest";
-    private static final long OPERATION_TIMEOUT_MS = 1500;
-
-    private TvInputManager mManager;
-    private Session mSession;
-    private final SessionCallback mSessionCallback;
-    private boolean mAvailability;
-    private TvInputListener mTvInputListener;
-    private HandlerThread mCallbackThread;
-    private Handler mCallbackHandler;
-
-    private CountDownLatch mAvailabilityChangeLatch;
-    private CountDownLatch mSessionCreationLatch;
-    private CountDownLatch mSessionReleaseLatch;
-
-    public TvInputManagerTest() {
-        mSessionCallback = new MockSessionCallback();
-    }
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-        if (TextUtils.isEmpty(MockTvInputInternalService.sInputId)) {
-            ComponentName componentName = new ComponentName(
-                    context.getPackageName(), MockTvInputInternalService.class.getName());
-            // TODO: Do not directly generate an input id.
-            MockTvInputInternalService.sInputId = componentName.flattenToShortString();
-        }
-        if (TextUtils.isEmpty(MockTvInputRemoteService.sInputId)) {
-            ComponentName componentName = new ComponentName(
-                    context.getPackageName(), MockTvInputRemoteService.class.getName());
-            // TODO: Do not directly generate an input id.
-            MockTvInputRemoteService.sInputId = componentName.flattenToShortString();
-        }
-        mManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
-    }
-
-    @Override
-    protected void setUp() {
-        mAvailability = false;
-        mSession = null;
-        MockTvInputInternalService.sInstance = null;
-        MockTvInputInternalService.sSession = null;
-        MockTvInputInternalService.sFailOnCreateSession = false;
-        mCallbackThread = new HandlerThread("CallbackThread");
-        mCallbackThread.start();
-        mCallbackHandler = new Handler(mCallbackThread.getLooper());
-    }
-
-    @Override
-    protected void tearDown() throws InterruptedException {
-        if (mTvInputListener != null) {
-            mManager.unregisterListener(MockTvInputInternalService.sInputId, mTvInputListener);
-            mManager.unregisterListener(MockTvInputRemoteService.sInputId, mTvInputListener);
-            mTvInputListener = null;
-        }
-        mCallbackThread.quit();
-        mCallbackThread.join();
-    }
-
-    public void testGetTvInputList() throws Exception {
-        // Check if the returned list includes the mock tv input services.
-        int mockServiceInstalled = 0;
-        for (TvInputInfo info : mManager.getTvInputList()) {
-            if (MockTvInputInternalService.sInputId.equals(info.getId())) {
-                ++mockServiceInstalled;
-            }
-            if (MockTvInputRemoteService.sInputId.equals(info.getId())) {
-                ++mockServiceInstalled;
-            }
-        }
-
-        // Verify the result.
-        assertEquals("Mock services must be listed", 2, mockServiceInstalled);
-    }
-
-    public void testCreateSession() throws Exception {
-        mSessionCreationLatch = new CountDownLatch(1);
-        // Make the mock service return a session on request.
-        mManager.createSession(MockTvInputInternalService.sInputId, mSessionCallback,
-                mCallbackHandler);
-
-        // Verify the result.
-        assertTrue(mSessionCreationLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertNotNull(mSession);
-
-        mSession.release();
-    }
-
-    public void testCreateSessionFailure() throws Exception {
-        mSessionCreationLatch = new CountDownLatch(1);
-        // Make the mock service return {@code null} on request.
-        MockTvInputInternalService.sFailOnCreateSession = true;
-        mManager.createSession(MockTvInputInternalService.sInputId, mSessionCallback,
-                mCallbackHandler);
-
-        // Verify the result.
-        assertTrue(mSessionCreationLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertNull(mSession);
-    }
-
-    public void testAvailabilityChanged() throws Exception {
-        // Register a listener for availability change.
-        MockTvInputInternalService.sInstanceLatch = new CountDownLatch(1);
-        mTvInputListener = new MockTvInputListener();
-        mManager.registerListener(MockTvInputInternalService.sInputId, mTvInputListener,
-                mCallbackHandler);
-
-        // Make sure that the mock service is created.
-        if (MockTvInputInternalService.sInstance == null) {
-            assertTrue(MockTvInputInternalService.sInstanceLatch.await(
-                    OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-
-        // Change the availability of the mock service.
-        mAvailability = mManager.getAvailability(MockTvInputInternalService.sInputId);
-        boolean newAvailiability = !mAvailability;
-        mAvailabilityChangeLatch = new CountDownLatch(1);
-        MockTvInputInternalService.sInstance.setAvailable(newAvailiability);
-
-        // Verify the result.
-        assertTrue(mAvailabilityChangeLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertEquals(newAvailiability, mAvailability);
-    }
-
-    public void testCrashOnCreateSession() throws Exception {
-        mSessionCreationLatch = new CountDownLatch(
-                MockTvInputRemoteService.MAX_SESSION_CREATION_BEFORE_CRASH + 1);
-        mSessionReleaseLatch =  new CountDownLatch(
-                MockTvInputRemoteService.MAX_SESSION_CREATION_BEFORE_CRASH);
-        // availability should be changed three times:
-        // 1) false -> true, when connected, 2) true -> false after crash, and
-        // 3) false -> true, after reconnected.
-        mAvailabilityChangeLatch = new CountDownLatch(3);
-        mTvInputListener = new MockTvInputListener();
-        mManager.registerListener(MockTvInputRemoteService.sInputId, mTvInputListener,
-                mCallbackHandler);
-
-        for (int i = 0; i < MockTvInputRemoteService.MAX_SESSION_CREATION_BEFORE_CRASH + 1; ++i) {
-            mManager.createSession(MockTvInputRemoteService.sInputId, mSessionCallback,
-                    mCallbackHandler);
-        }
-
-        // Verify the result.
-        assertTrue(mSessionReleaseLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertTrue(mSessionCreationLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertTrue(mAvailabilityChangeLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    public void testCrashOnTune() throws Exception {
-        mSessionCreationLatch = new CountDownLatch(1);
-        mSessionReleaseLatch =  new CountDownLatch(1);
-        // availability should be changed three times:
-        // 1) false -> true, when connected, 2) true -> false after crash, and
-        // 3) false -> true, after reconnected.
-        mAvailabilityChangeLatch = new CountDownLatch(3);
-
-        mTvInputListener = new MockTvInputListener();
-        mManager.registerListener(MockTvInputRemoteService.sInputId, mTvInputListener,
-                mCallbackHandler);
-        mManager.createSession(MockTvInputRemoteService.sInputId, mSessionCallback,
-                mCallbackHandler);
-
-        assertTrue(mSessionCreationLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        Uri channelUri = ContentUris.withAppendedId(TvContract.Channels.CONTENT_URI, 0);
-        mSession.tune(channelUri);
-        assertTrue(mSessionReleaseLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertNull(mSession);
-        assertTrue(mAvailabilityChangeLatch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    private class MockTvInputListener extends TvInputListener {
-        @Override
-        public void onAvailabilityChanged(String inputId, boolean isAvailable) {
-            mAvailability = isAvailable;
-            if (mAvailabilityChangeLatch != null) {
-                mAvailabilityChangeLatch.countDown();
-            }
-        }
-    }
-
-    private class MockSessionCallback extends SessionCallback {
-        @Override
-        public void onSessionCreated(Session session) {
-            mSession = session;
-            if (mSessionCreationLatch != null) {
-                mSessionCreationLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onSessionReleased(Session session) {
-            mSession = null;
-            if (mSessionReleaseLatch != null) {
-                mSessionReleaseLatch.countDown();
-            }
-        }
-    }
-
-    public static class MockTvInputInternalService extends TvInputService {
-        static String sInputId;
-        static CountDownLatch sInstanceLatch;
-        static MockTvInputInternalService sInstance;
-        static TvInputSessionImpl sSession;
-
-        static boolean sFailOnCreateSession;
-
-        @Override
-        public void onCreate() {
-            super.onCreate();
-            sInstance = this;
-            sSession = new MockTvInputInternalSessionImpl();
-            if (sInstanceLatch != null) {
-                sInstanceLatch.countDown();
-            }
-        }
-
-        @Override
-        public TvInputSessionImpl onCreateSession() {
-            return sFailOnCreateSession ? null : sSession;
-        }
-
-        class MockTvInputInternalSessionImpl extends TvInputSessionImpl {
-            public MockTvInputInternalSessionImpl() { }
-
-            @Override
-            public void onRelease() { }
-
-            @Override
-            public boolean onSetSurface(Surface surface) {
-                return false;
-            }
-
-            @Override
-            public void onSetVolume(float volume) { }
-
-            @Override
-            public boolean onTune(Uri channelUri) {
-                return false;
-            }
-        }
-    }
-
-    public static class MockTvInputRemoteService extends TvInputService {
-        public static final int MAX_SESSION_CREATION_BEFORE_CRASH = 2;
-        static String sInputId;
-
-        private int mSessionCreationBeforeCrash;
-
-        @Override
-        public void onCreate() {
-            super.onCreate();
-            mSessionCreationBeforeCrash = MAX_SESSION_CREATION_BEFORE_CRASH;
-            setAvailable(true);
-        }
-
-        @Override
-        public TvInputSessionImpl onCreateSession() {
-            if (mSessionCreationBeforeCrash > 0) {
-                --mSessionCreationBeforeCrash;
-                return new MockTvInputRemoteSessionImpl();
-            }
-            android.os.Process.killProcess(android.os.Process.myPid());
-            return null;
-        }
-
-        class MockTvInputRemoteSessionImpl extends TvInputSessionImpl {
-            public MockTvInputRemoteSessionImpl() { }
-
-            @Override
-            public void onRelease() { }
-
-            @Override
-            public boolean onSetSurface(Surface surface) {
-                return false;
-            }
-
-            @Override
-            public void onSetVolume(float volume) { }
-
-            @Override
-            public boolean onTune(Uri channelUri) {
-                android.os.Process.killProcess(android.os.Process.myPid());
-                return false;
-            }
-        }
-    }
-}