Merge "Fix CtsMediaHostTestCases" into oc-mr1-dev
diff --git a/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml b/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
index 60e82dd..5ae6f96 100644
--- a/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
+++ b/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
@@ -19,7 +19,17 @@
 
     <uses-sdk android:minSdkVersion="26"/>
 
-    <application />
+    <application
+        android:testOnly="true">
+        <service
+            android:name=".MediaSessionManagerTest"
+            android:label="MediaSessionManagerTest"
+            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService" />
+            </intent-filter>
+        </service>
+    </application>
 
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java b/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
index 2186038..02d8107 100644
--- a/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
+++ b/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
@@ -17,12 +17,20 @@
 package android.media.session.cts;
 
 import static android.media.cts.MediaSessionTestHelperConstants.MEDIA_SESSION_TEST_HELPER_PKG;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import android.content.Context;
 import android.content.ComponentName;
-import android.test.AndroidTestCase;
-import android.media.session.MediaSessionManager;
+import android.content.Context;
 import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
+import android.service.notification.NotificationListenerService;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
 
 import java.util.List;
 
@@ -31,22 +39,25 @@
  * <p>Don't run tests here directly. They aren't stand-alone tests and each test will be run
  * indirectly by the host-side test CtsMediaHostTestCases after the proper device setup.
  */
-public class MediaSessionManagerTest extends AndroidTestCase {
+@SmallTest
+public class MediaSessionManagerTest extends NotificationListenerService {
+    private ComponentName mComponentName;
     private MediaSessionManager mMediaSessionManager;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mMediaSessionManager = (MediaSessionManager) getContext().getSystemService(
+        Context context = InstrumentationRegistry.getTargetContext();
+        mMediaSessionManager = (MediaSessionManager) context.getSystemService(
                 Context.MEDIA_SESSION_SERVICE);
+        mComponentName = new ComponentName(context, MediaSessionManagerTest.class);
     }
 
     /**
      * Tests if the MediaSessionTestHelper doesn't have an active media session.
      */
+    @Test
     public void testGetActiveSessions_noMediaSessionFromMediaSessionTestHelper() throws Exception {
-        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(
-                createFakeNotificationListener());
+        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(mComponentName);
         for (MediaController controller : controllers) {
             if (controller.getPackageName().equals(MEDIA_SESSION_TEST_HELPER_PKG)) {
                 fail("Media session for the media session app shouldn't be available");
@@ -58,9 +69,9 @@
     /**
      * Tests if the MediaSessionTestHelper has an active media session.
      */
+    @Test
     public void testGetActiveSessions_hasMediaSessionFromMediaSessionTestHelper() throws Exception {
-        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(
-                createFakeNotificationListener());
+        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(mComponentName);
         for (MediaController controller : controllers) {
             if (controller.getPackageName().equals(MEDIA_SESSION_TEST_HELPER_PKG)) {
                 // Test success
@@ -73,18 +84,9 @@
     /**
      * Tests if there's no media session.
      */
+    @Test
     public void testGetActiveSessions_noMediaSession() throws Exception {
-        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(
-                createFakeNotificationListener());
+        List<MediaController> controllers = mMediaSessionManager.getActiveSessions(mComponentName);
         assertTrue(controllers.isEmpty());
     }
-
-    /**
-     * Returns the ComponentName of the notification listener for this test.
-     * <p>Notification listener will be enabled by the host-side test.
-     */
-    private ComponentName createFakeNotificationListener() {
-        return new ComponentName(getContext(), MediaSessionManagerTest.class);
-    }
 }
-
diff --git a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
index da5b354..93c4eee 100644
--- a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
+++ b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
@@ -30,10 +30,9 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringJoiner;
-import java.util.StringTokenizer;
+import java.util.ArrayList;
+import java.util.List;
+
 
 /**
  * Host-side test for the media session manager that installs and runs device-side tests after the
@@ -56,29 +55,22 @@
     private static final String DEVICE_SIDE_TEST_CLASS =
             "android.media.session.cts.MediaSessionManagerTest";
 
-    private static final String SETTINGS_NOTIFICATION_LISTENER_NAMESPACE = "secure";
-    private static final String SETTINGS_NOTIFICATION_LISTENER_NAME =
-            "enabled_notification_listeners";
-
-    // Keep the original notification listener list to clean up.
-    private Map<Integer, String> mNotificationListeners;
+    private final List<Integer> mNotificationListeners = new ArrayList<>();
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mNotificationListeners = new HashMap<>();
 
         // Ensure that the previously running media session test helper app doesn't exist.
         getDevice().uninstallPackage(MEDIA_SESSION_TEST_HELPER_PKG);
+        mNotificationListeners.clear();
     }
 
     @Override
     public void tearDown() throws Exception {
         // Cleanup
-        for (int userId : mNotificationListeners.keySet()) {
-            String notificationListener = mNotificationListeners.get(userId);
-            putSettings(SETTINGS_NOTIFICATION_LISTENER_NAMESPACE,
-                    SETTINGS_NOTIFICATION_LISTENER_NAME, notificationListener, userId);
+        for (int userId : mNotificationListeners) {
+            setAllowGetActiveSessionForTest(false, userId);
         }
         super.tearDown();
     }
@@ -90,7 +82,7 @@
     public void testGetActiveSessions_primaryUser() throws Exception {
         int primaryUserId = getDevice().getPrimaryUserId();
 
-        allowGetActiveSessionForTest(primaryUserId);
+        setAllowGetActiveSessionForTest(true, primaryUserId);
         installAppAsUser(DEVICE_SIDE_TEST_APK, primaryUserId);
         runTest("testGetActiveSessions_noMediaSessionFromMediaSessionTestHelper");
 
@@ -116,7 +108,7 @@
         // Test if another user can get the session.
         int newUser = createAndStartUser();
         installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
-        allowGetActiveSessionForTest(newUser);
+        setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
     }
@@ -136,7 +128,7 @@
         // Remove the created user first not to exceed system's user number limit.
         int newUser = createAndStartRestrictedProfile(getDevice().getPrimaryUserId());
         installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
-        allowGetActiveSessionForTest(newUser);
+        setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
     }
@@ -156,7 +148,7 @@
         // Remove the created user first not to exceed system's user number limit.
         int newUser = createAndStartManagedProfile(getDevice().getPrimaryUserId());
         installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
-        allowGetActiveSessionForTest(newUser);
+        setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
     }
@@ -172,43 +164,24 @@
     }
 
     /**
-     * Allows the {@link #DEVICE_SIDE_TEST_CLASS} to call
-     * {@link MediaSessionManager#getActiveSessions} for testing.
+     * Sets to allow or disallow the {@link #DEVICE_SIDE_TEST_CLASS}
+     * to call {@link MediaSessionManager#getActiveSessions} for testing.
      * <p>{@link MediaSessionManager#getActiveSessions} bypasses the permission check if the
-     * caller is the enabled notification listener. This method uses the behavior by making
-     * {@link #DEVICE_SIDE_TEST_CLASS} as the notification listener. So any change in this
-     * should be also applied to the class.
+     * caller is the enabled notification listener. This method uses the behavior by allowing
+     * this class as the notification listener service.
      * <p>Note that the device-side test {@link android.media.cts.MediaSessionManagerTest} already
      * covers the test for failing {@link MediaSessionManager#getActiveSessions} without the
      * permission nor the notification listener.
      */
-    private void allowGetActiveSessionForTest(int userId) throws Exception {
-        final String NOTIFICATION_LISTENER_DELIM = ":";
-        if (mNotificationListeners.get(userId) != null) {
-            // Already enabled.
-            return;
-        }
-        String list = getSettings(SETTINGS_NOTIFICATION_LISTENER_NAMESPACE,
-                SETTINGS_NOTIFICATION_LISTENER_NAME, userId);
-
+    private void setAllowGetActiveSessionForTest(boolean allow, int userId) throws Exception {
         String notificationListener = DEVICE_SIDE_TEST_PKG + "/" + DEVICE_SIDE_TEST_CLASS;
-        // Ensure that the list doesn't contain notificationListener already.
-        // This can happen if the test is killed while running.
-        StringTokenizer tokenizer = new StringTokenizer(list, NOTIFICATION_LISTENER_DELIM);
-        StringJoiner joiner = new StringJoiner(NOTIFICATION_LISTENER_DELIM);
-        while (tokenizer.hasMoreTokens()) {
-            String token = tokenizer.nextToken();
-            if (!token.isEmpty() && !token.equals(notificationListener)) {
-                joiner.add(token);
-            }
+        String command = "cmd notification "
+                + ((allow) ? "allow_listener " : "disallow_listener ")
+                + notificationListener + " " + userId;
+        executeShellCommand(command);
+        if (allow) {
+            mNotificationListeners.add(userId);
         }
-        list = joiner.toString();
-        // Preserve the original list.
-        mNotificationListeners.put(userId, list);
-        // Allow get active sessions by setting notification listener.
-        joiner.add(notificationListener);
-        putSettings(SETTINGS_NOTIFICATION_LISTENER_NAMESPACE,
-                SETTINGS_NOTIFICATION_LISTENER_NAME, joiner.toString(), userId);
     }
 
     private void sendControlCommand(int userId, int flag) throws Exception {