diff --git a/packages/MediaComponents/test/Android.mk b/packages/MediaComponents/test/Android.mk
deleted file mode 100644
index ea053e0..0000000
--- a/packages/MediaComponents/test/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2018 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# TODO(jaewan): Copy this to the CTS as well
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    mockito-target-minus-junit4 \
-    compatibility-device-util
-
-LOCAL_PACKAGE_NAME := MediaComponentsTest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-include $(BUILD_PACKAGE)
diff --git a/packages/MediaComponents/test/AndroidManifest.xml b/packages/MediaComponents/test/AndroidManifest.xml
deleted file mode 100644
index 5ebe31a..0000000
--- a/packages/MediaComponents/test/AndroidManifest.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.media.test">
-
-    <application android:label="Media API Test">
-        <uses-library android:name="android.test.runner" />
-
-        <activity android:name="android.media.MockActivity" />
-
-        <!-- Keep the test services synced together with the TestUtils.java -->
-        <service android:name="android.media.MockMediaSessionService2">
-            <intent-filter>
-                <action android:name="android.media.MediaSessionService2" />
-            </intent-filter>
-            <meta-data android:name="android.media.session" android:value="TestSession" />
-        </service>
-        <!-- Keep the test services synced together with the MockMediaLibraryService -->
-        <service android:name="android.media.MockMediaLibraryService2">
-            <intent-filter>
-                <action android:name="android.media.MediaLibraryService2" />
-            </intent-filter>
-            <meta-data android:name="android.media.session" android:value="TestLibrary" />
-        </service>
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.media.test"
-        android:label="Media API test" />
-
-</manifest>
diff --git a/packages/MediaComponents/test/runtest.sh b/packages/MediaComponents/test/runtest.sh
deleted file mode 100644
index edce230..0000000
--- a/packages/MediaComponents/test/runtest.sh
+++ /dev/null
@@ -1,191 +0,0 @@
-#!/bin/bash
-# Copyright 2018 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.
-
-# Usage '. runtest.sh'
-
-function _runtest_mediacomponent_usage() {
-  echo 'runtest-MediaComponents [option]: Run MediaComponents test'
-  echo '     -h|--help: This help'
-  echo '     --skip: Skip build. Just rerun-tests.'
-  echo '     --min: Only rebuild test apk and updatable library.'
-  echo '     -s [device_id]: Specify a device name to run test against.'
-  echo '                     You can define ${ADBHOST} instead.'
-  echo '     -r [count]: Repeat tests for given count. It will stop when fails.'
-  echo '     --ignore: Keep repeating tests even when it fails.'
-  echo '     -t [test]: Only run the specific test. Can be either a class or a method.'
-}
-
-function runtest-MediaComponents() {
-  # Edit here if you want to support other tests.
-  # List up libs and apks in the media_api needed for tests, and place test target at the last.
-  local TEST_PACKAGE_DIR=("frameworks/av/packages/MediaComponents/test")
-  local BUILD_TARGETS=("MediaComponents" "MediaComponentsTest")
-  local INSTALL_TARGETS=("MediaComponentsTest")
-  local TEST_RUNNER="android.support.test.runner.AndroidJUnitRunner"
-  local DEPENDENCIES=("mockito-target-minus-junit4" "android-support-test" "compatibility-device-util")
-
-  if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
-    echo "Needs to lunch a target first"
-    return
-  fi
-
-  local old_path=${OLDPWD}
-  while true; do
-    local OPTION_SKIP="false"
-    local OPTION_MIN="false"
-    local OPTION_REPEAT_COUNT="1"
-    local OPTION_IGNORE="false"
-    local OPTION_TEST_TARGET=""
-    local adbhost_local
-    while (( "$#" )); do
-      case "${1}" in
-        -h|--help)
-          _runtest_mediacomponent_usage
-          return
-          ;;
-        --skip)
-          OPTION_SKIP="true"
-          ;;
-        --min)
-          OPTION_MIN="true"
-          ;;
-        -s)
-          shift
-          adbhost_local=${1}
-          ;;
-        -r)
-          shift
-          OPTION_REPEAT_COUNT="${1}"
-          ;;
-        --ignore)
-          OPTION_IGNORE="true"
-          ;;
-        -t)
-          shift
-          OPTION_TEST_TARGET="${1}"
-      esac
-      shift
-    done
-
-    # Build adb command.
-    local adb
-    if [[ -z "${adbhost_local}" ]]; then
-      adbhost_local=${ADBHOST}
-    fi
-    if [[ -z "${adbhost_local}" ]]; then
-      local device_count=$(adb devices | sed '/^[[:space:]]*$/d' | wc -l)
-      if [[ "${device_count}" != "2" ]]; then
-        echo "Too many devices. Specify a device." && break
-      fi
-      adb="adb"
-    else
-      adb="adb -s ${adbhost_local}"
-    fi
-
-    local target_dir="${ANDROID_BUILD_TOP}/${TEST_PACKAGE_DIR}"
-    local TEST_PACKAGE=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\.]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
-
-    if [[ "${OPTION_SKIP}" != "true" ]]; then
-      # Build dependencies if needed.
-      local dependency
-      local build_dependency=""
-      for dependency in ${DEPENDENCIES[@]}; do
-        if [[ "${dependency}" == "out/"* ]]; then
-          if [[ ! -f ${ANDROID_BUILD_TOP}/${dependency} ]]; then
-            build_dependency="true"
-            break
-          fi
-        else
-          if [[ "$(find ${OUT} -name ${dependency}_intermediates | wc -l)" == "0" ]]; then
-            build_dependency="true"
-            break
-          fi
-        fi
-      done
-      if [[ "${build_dependency}" == "true" ]]; then
-        echo "Building dependencies. Will only print stderr."
-        m ${DEPENDENCIES[@]} -j > /dev/null
-      fi
-
-      # Build test apk and required apk.
-      local build_targets="${BUILD_TARGETS[@]}"
-      if [[ "${OPTION_MIN}" != "true" ]]; then
-        build_targets="${build_targets} droid"
-      fi
-      m ${build_targets} -j || break
-
-      ${adb} root
-      ${adb} remount
-      ${adb} shell stop
-      ${adb} shell setprop log.tag.MediaSessionService DEBUG
-      ${adb} sync
-      ${adb} shell start
-      ${adb} wait-for-device || break
-      # Ensure package manager is loaded.
-      sleep 15
-
-      # Install apks
-      local install_failed="false"
-      for target in ${INSTALL_TARGETS[@]}; do
-        echo "${target}"
-        local target_dir=$(mgrep -l -e '^LOCAL_PACKAGE_NAME.*'"${target}$")
-        if [[ -z ${target_dir} ]]; then
-          continue
-        fi
-        target_dir=$(dirname ${target_dir})
-        local package=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\._]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
-        local apk_path=$(find ${OUT}/system ${OUT}/data -name ${target}.apk)
-        local apk_num=$(find ${OUT}/system ${OUT}/data -name ${target}.apk | wc -l)
-        if [[ "${apk_num}" != "1" ]]; then
-          echo "Cannot locate a ${target}.apk. Found ${apk_num} apks" && break
-        fi
-        echo "Installing ${target}.apk. path=${apk_path}"
-        ${adb} install -r ${apk_path}
-        if [[ "${?}" != "0" ]]; then
-          install_failed="true"
-          break
-        fi
-      done
-      if [[ "${install_failed}" == "true" ]]; then
-        echo "Failed to install. Test wouldn't run."
-        break
-      fi
-    fi
-
-    local test_target=""
-    if [[ -n "${OPTION_TEST_TARGET}" ]]; then
-      test_target="-e class ${OPTION_TEST_TARGET}"
-    fi
-
-    local i
-    local tmpfile=$(tempfile)
-    for ((i=1; i <= ${OPTION_REPEAT_COUNT}; i++)); do
-      echo "Run test ${i}/${OPTION_REPEAT_COUNT}"
-      ${adb} shell am instrument ${test_target} -w ${TEST_PACKAGE}/${TEST_RUNNER} >& ${tmpfile}
-      cat ${tmpfile}
-      if [[ "${OPTION_IGNORE}" != "true" ]]; then
-        if [[ -n "$(grep ${tmpfile} -e 'FAILURE\|crashed')" ]]; then
-          # am instrument doesn't return error code so need to grep result message instead
-          break
-        fi
-      fi
-    done
-    rm ${tmpfile}
-    break
-  done
-}
-
-echo "Following functions are added to your environment:"
-_runtest_mediacomponent_usage
diff --git a/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java b/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java
deleted file mode 100644
index e58bd02..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.fail;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.media.MediaBrowser2.BrowserCallback;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.os.Process;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests {@link MediaBrowser2}.
- * <p>
- * This test inherits {@link MediaController2Test} to ensure that inherited APIs from
- * {@link MediaController2} works cleanly.
- */
-// TODO(jaewan): Implement host-side test so browser and service can run in different processes.
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaBrowser2Test extends MediaController2Test {
-    private static final String TAG = "MediaBrowser2Test";
-
-    @Override
-    TestControllerInterface onCreateController(@NonNull SessionToken2 token,
-            @Nullable TestControllerCallbackInterface callback) {
-        if (callback == null) {
-            callback = new TestBrowserCallbackInterface() {};
-        }
-        return new TestMediaBrowser(mContext, token, new TestBrowserCallback(callback));
-    }
-
-    interface TestBrowserCallbackInterface extends TestControllerCallbackInterface {
-        // Browser specific callbacks
-        default void onGetLibraryRootDone(Bundle rootHints, String rootMediaId, Bundle rootExtra) {}
-        default void onGetItemDone(String mediaId, MediaItem2 result) {}
-        default void onChildrenChanged(String parentId, int itemCount, Bundle extras) {}
-        default void onGetChildrenDone(String parentId, int page, int pageSize,
-                List<MediaItem2> result, Bundle extras) {}
-        default void onSearchResultChanged(String query, int itemCount, Bundle extras) {}
-        default void onGetSearchResultDone(String query, int page, int pageSize,
-                List<MediaItem2> result, Bundle extras) {}
-    }
-
-    @Test
-    public void testGetLibraryRoot() throws InterruptedException {
-        final Bundle param = new Bundle();
-        param.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetLibraryRootDone(Bundle rootHints, String rootMediaId,
-                    Bundle rootExtra) {
-                assertTrue(TestUtils.equals(param, rootHints));
-                assertEquals(MockMediaLibraryService2.ROOT_ID, rootMediaId);
-                assertTrue(TestUtils.equals(MockMediaLibraryService2.EXTRAS, rootExtra));
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser =
-                (MediaBrowser2) createController(token,true, callback);
-        browser.getLibraryRoot(param);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetItem() throws InterruptedException {
-        final String mediaId = MockMediaLibraryService2.MEDIA_ID_GET_ITEM;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetItemDone(String mediaIdOut, MediaItem2 result) {
-                assertEquals(mediaId, mediaIdOut);
-                assertNotNull(result);
-                assertEquals(mediaId, result.getMediaId());
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getItem(mediaId);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetItemNullResult() throws InterruptedException {
-        final String mediaId = "random_media_id";
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetItemDone(String mediaIdOut, MediaItem2 result) {
-                assertEquals(mediaId, mediaIdOut);
-                assertNull(result);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getItem(mediaId);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildren() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID;
-        final int page = 4;
-        final int pageSize = 10;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertEquals(parentId, parentIdOut);
-                assertEquals(page, pageOut);
-                assertEquals(pageSize, pageSizeOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertNotNull(result);
-
-                int fromIndex = (page - 1) * pageSize;
-                int toIndex = Math.min(page * pageSize, MockMediaLibraryService2.CHILDREN_COUNT);
-
-                // Compare the given results with originals.
-                for (int originalIndex = fromIndex; originalIndex < toIndex; originalIndex++) {
-                    int relativeIndex = originalIndex - fromIndex;
-                    assertEquals(
-                            MockMediaLibraryService2.GET_CHILDREN_RESULT.get(originalIndex)
-                                    .getMediaId(),
-                            result.get(relativeIndex).getMediaId());
-                }
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, page, pageSize, extras);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildrenEmptyResult() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID_NO_CHILDREN;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertNotNull(result);
-                assertEquals(0, result.size());
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, 1, 1, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildrenNullResult() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID_ERROR;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertNull(result);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, 1, 1, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testSearch() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY;
-        final int page = 4;
-        final int pageSize = 10;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latchForSearch = new CountDownLatch(1);
-        final CountDownLatch latchForGetSearchResult = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(MockMediaLibraryService2.SEARCH_RESULT_COUNT, itemCount);
-                latchForSearch.countDown();
-            }
-
-            @Override
-            public void onGetSearchResultDone(String queryOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertEquals(page, pageOut);
-                assertEquals(pageSize, pageSizeOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertNotNull(result);
-
-                int fromIndex = (page - 1) * pageSize;
-                int toIndex = Math.min(
-                        page * pageSize, MockMediaLibraryService2.SEARCH_RESULT_COUNT);
-
-                // Compare the given results with originals.
-                for (int originalIndex = fromIndex; originalIndex < toIndex; originalIndex++) {
-                    int relativeIndex = originalIndex - fromIndex;
-                    assertEquals(
-                            MockMediaLibraryService2.SEARCH_RESULT.get(originalIndex).getMediaId(),
-                            result.get(relativeIndex).getMediaId());
-                }
-                latchForGetSearchResult.countDown();
-            }
-        };
-
-        // Request the search.
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latchForSearch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-
-        // Get the search result.
-        browser.getSearchResult(query, page, pageSize, extras);
-        assertTrue(latchForGetSearchResult.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSearchTakesTime() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY_TAKES_TIME;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(MockMediaLibraryService2.SEARCH_RESULT_COUNT, itemCount);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latch.await(
-                MockMediaLibraryService2.SEARCH_TIME_IN_MS + WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSearchEmptyResult() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY_EMPTY_RESULT;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(0, itemCount);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSubscribe() throws InterruptedException {
-        final String testParentId = "testSubscribeId";
-        final Bundle testExtras = new Bundle();
-        testExtras.putString(testParentId, testParentId);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy callbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onSubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId,
-                    @Nullable Bundle extras) {
-                if (Process.myUid() == info.getUid()) {
-                    assertEquals(testParentId, parentId);
-                    assertTrue(TestUtils.equals(testExtras, extras));
-                    latch.countDown();
-                }
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(callbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token);
-        browser.subscribe(testParentId, testExtras);
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testUnsubscribe() throws InterruptedException {
-        final String testParentId = "testUnsubscribeId";
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy callbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId) {
-                if (Process.myUid() == info.getUid()) {
-                    assertEquals(testParentId, parentId);
-                    latch.countDown();
-                }
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(callbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token);
-        browser.unsubscribe(testParentId);
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testBrowserCallback_notifyChildrenChanged() throws InterruptedException {
-        // TODO(jaewan): Add test for the notifyChildrenChanged itself.
-        final String testParentId1 = "testBrowserCallback_notifyChildrenChanged_unexpectedParent";
-        final String testParentId2 = "testBrowserCallback_notifyChildrenChanged";
-        final int testChildrenCount = 101;
-        final Bundle testExtras = new Bundle();
-        testExtras.putString(testParentId1, testParentId1);
-
-        final CountDownLatch latch = new CountDownLatch(3);
-        final SessionCallbackProxy sessionCallbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public CommandGroup onConnect(@NonNull MediaSession2 session,
-                    @NonNull ControllerInfo controller) {
-                if (Process.myUid() == controller.getUid()) {
-                    assertTrue(session instanceof MediaLibrarySession);
-                    if (mSession != null) {
-                        mSession.close();
-                    }
-                    mSession = session;
-                    // Shouldn't trigger onChildrenChanged() for the browser, because it hasn't
-                    // subscribed.
-                    ((MediaLibrarySession) session).notifyChildrenChanged(
-                            testParentId1, testChildrenCount, null);
-                    ((MediaLibrarySession) session).notifyChildrenChanged(
-                            controller, testParentId1, testChildrenCount, null);
-                }
-                return super.onConnect(session, controller);
-            }
-
-            @Override
-            public void onSubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId,
-                    @Nullable Bundle extras) {
-                if (Process.myUid() == info.getUid()) {
-                    session.notifyChildrenChanged(testParentId2, testChildrenCount, null);
-                    session.notifyChildrenChanged(info, testParentId2, testChildrenCount,
-                            testExtras);
-                }
-            }
-        };
-        final TestBrowserCallbackInterface controllerCallbackProxy =
-                new TestBrowserCallbackInterface() {
-                    @Override
-                    public void onChildrenChanged(String parentId, int itemCount, Bundle extras) {
-                        switch ((int) latch.getCount()) {
-                            case 3:
-                                assertEquals(testParentId2, parentId);
-                                assertEquals(testChildrenCount, itemCount);
-                                assertNull(extras);
-                                latch.countDown();
-                                break;
-                            case 2:
-                                assertEquals(testParentId2, parentId);
-                                assertEquals(testChildrenCount, itemCount);
-                                assertTrue(TestUtils.equals(testExtras, extras));
-                                latch.countDown();
-                                break;
-                            default:
-                                // Unexpected call.
-                                fail();
-                        }
-                    }
-                };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(sessionCallbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        final MediaBrowser2 browser = (MediaBrowser2) createController(
-                token, true, controllerCallbackProxy);
-        assertTrue(mSession instanceof MediaLibrarySession);
-        browser.subscribe(testParentId2, null);
-        // This ensures that onChildrenChanged() is only called for the expected reasons.
-        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    public static class TestBrowserCallback extends BrowserCallback
-            implements WaitForConnectionInterface {
-        private final TestControllerCallbackInterface mCallbackProxy;
-        public final CountDownLatch connectLatch = new CountDownLatch(1);
-        public final CountDownLatch disconnectLatch = new CountDownLatch(1);
-
-        TestBrowserCallback(TestControllerCallbackInterface callbackProxy) {
-            if (callbackProxy == null) {
-                throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
-            }
-            mCallbackProxy = callbackProxy;
-        }
-
-        @CallSuper
-        @Override
-        public void onConnected(MediaController2 controller, CommandGroup commands) {
-            connectLatch.countDown();
-        }
-
-        @CallSuper
-        @Override
-        public void onDisconnected(MediaController2 controller) {
-            disconnectLatch.countDown();
-        }
-
-        @Override
-        public void onPlaybackStateChanged(MediaController2 controller, PlaybackState2 state) {
-            mCallbackProxy.onPlaybackStateChanged(state);
-        }
-
-        @Override
-        public void onPlaylistParamsChanged(MediaController2 controller, PlaylistParams params) {
-            mCallbackProxy.onPlaylistParamsChanged(params);
-        }
-
-        @Override
-        public void onPlaybackInfoChanged(MediaController2 controller,
-                MediaController2.PlaybackInfo info) {
-            mCallbackProxy.onPlaybackInfoChanged(info);
-        }
-
-        @Override
-        public void onCustomCommand(MediaController2 controller, Command command, Bundle args,
-                ResultReceiver receiver) {
-            mCallbackProxy.onCustomCommand(command, args, receiver);
-        }
-
-        @Override
-        public void onCustomLayoutChanged(MediaController2 controller, List<CommandButton> layout) {
-            mCallbackProxy.onCustomLayoutChanged(layout);
-        }
-
-        @Override
-        public void onAllowedCommandsChanged(MediaController2 controller, CommandGroup commands) {
-            mCallbackProxy.onAllowedCommandsChanged(commands);
-        }
-
-        @Override
-        public void onGetLibraryRootDone(MediaBrowser2 browser, Bundle rootHints,
-                String rootMediaId, Bundle rootExtra) {
-            super.onGetLibraryRootDone(browser, rootHints, rootMediaId, rootExtra);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetLibraryRootDone(rootHints, rootMediaId, rootExtra);
-            }
-        }
-
-        @Override
-        public void onGetItemDone(MediaBrowser2 browser, String mediaId, MediaItem2 result) {
-            super.onGetItemDone(browser, mediaId, result);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy).onGetItemDone(mediaId, result);
-            }
-        }
-
-        @Override
-        public void onGetChildrenDone(MediaBrowser2 browser, String parentId, int page,
-                int pageSize, List<MediaItem2> result, Bundle extras) {
-            super.onGetChildrenDone(browser, parentId, page, pageSize, result, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetChildrenDone(parentId, page, pageSize, result, extras);
-            }
-        }
-
-        @Override
-        public void onSearchResultChanged(MediaBrowser2 browser, String query, int itemCount,
-                Bundle extras) {
-            super.onSearchResultChanged(browser, query, itemCount, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onSearchResultChanged(query, itemCount, extras);
-            }
-        }
-
-        @Override
-        public void onGetSearchResultDone(MediaBrowser2 browser, String query, int page,
-                int pageSize, List<MediaItem2> result, Bundle extras) {
-            super.onGetSearchResultDone(browser, query, page, pageSize, result, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetSearchResultDone(query, page, pageSize, result, extras);
-            }
-        }
-
-        @Override
-        public void onChildrenChanged(MediaBrowser2 browser, String parentId, int itemCount,
-                Bundle extras) {
-            super.onChildrenChanged(browser, parentId, itemCount, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onChildrenChanged(parentId, itemCount, extras);
-            }
-        }
-
-        @Override
-        public void waitForConnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(connectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(connectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void waitForDisconnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(disconnectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(disconnectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-    }
-
-    public class TestMediaBrowser extends MediaBrowser2 implements TestControllerInterface {
-        private final BrowserCallback mCallback;
-
-        public TestMediaBrowser(@NonNull Context context, @NonNull SessionToken2 token,
-                @NonNull ControllerCallback callback) {
-            super(context, token, sHandlerExecutor, (BrowserCallback) callback);
-            mCallback = (BrowserCallback) callback;
-        }
-
-        @Override
-        public BrowserCallback getCallback() {
-            return mCallback;
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaController2Test.java b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
deleted file mode 100644
index 2237d18..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaController2Test.java
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.MediaSession2.SessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.annotation.NonNull;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static android.media.TestUtils.ensurePlaylistParamsModeEquals;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests {@link MediaController2}.
- */
-// TODO(jaewan): Implement host-side test so controller and session can run in different processes.
-// TODO(jaewan): Fix flaky failure -- see MediaController2Impl.getController()
-// TODO(jaeawn): Revisit create/close session in the sHandler. It's no longer necessary.
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@FlakyTest
-public class MediaController2Test extends MediaSession2TestBase {
-    private static final String TAG = "MediaController2Test";
-
-    PendingIntent mIntent;
-    MediaSession2 mSession;
-    MediaController2 mController;
-    MockPlayer mPlayer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final Intent sessionActivity = new Intent(mContext, MockActivity.class);
-        // Create this test specific MediaSession2 to use our own Handler.
-        mIntent = PendingIntent.getActivity(mContext, 0, sessionActivity, 0);
-
-        mPlayer = new MockPlayer(1);
-        mSession = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                .setSessionActivity(mIntent)
-                .setId(TAG).build();
-        mController = createController(mSession.getToken());
-        TestServiceRegistry.getInstance().setHandler(sHandler);
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        if (mSession != null) {
-            mSession.close();
-        }
-        TestServiceRegistry.getInstance().cleanUp();
-    }
-
-    @Test
-    public void testPlay() throws InterruptedException {
-        mController.play();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPlayCalled);
-    }
-
-    @Test
-    public void testPause() throws InterruptedException {
-        mController.pause();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPauseCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToPreviousItem() throws InterruptedException {
-        mController.skipToPreviousItem();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSkipToPreviousCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToNextItem() throws InterruptedException {
-        mController.skipToNextItem();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSkipToNextCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testStop() throws InterruptedException {
-        mController.stop();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mStopCalled);
-    }
-
-    @Test
-    public void testPrepare() throws InterruptedException {
-        mController.prepare();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPrepareCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testFastForward() throws InterruptedException {
-        mController.fastForward();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mFastForwardCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testRewind() throws InterruptedException {
-        mController.rewind();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mRewindCalled);
-    }
-
-    @Test
-    public void testSeekTo() throws InterruptedException {
-        final long seekPosition = 12125L;
-        mController.seekTo(seekPosition);
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSeekToCalled);
-        assertEquals(seekPosition, mPlayer.mSeekPosition);
-    }
-
-    // TODO(jaewan): Re-enable this test
-    /*
-    @Test
-    public void testSetCurrentPlaylistItem() throws InterruptedException {
-        final
-        final int itemIndex = 9;
-        mController.skipToPlaylistItem(itemIndex);
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSetCurrentPlaylistCalled);
-        assertEquals(itemIndex, mPlayer.mCurrentItem);
-    }
-    */
-
-    @Test
-    public void testGetSessionActivity() throws InterruptedException {
-        PendingIntent sessionActivity = mController.getSessionActivity();
-        assertEquals(mContext.getPackageName(), sessionActivity.getCreatorPackage());
-        assertEquals(Process.myUid(), sessionActivity.getCreatorUid());
-    }
-
-    @Ignore
-    @Test
-    public void testGetSetPlaylistParams() throws Exception {
-        final PlaylistParams params = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL,
-                PlaylistParams.SHUFFLE_MODE_ALL,
-                null /* PlaylistMetadata */);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistParamsChanged(PlaylistParams givenParams) {
-                ensurePlaylistParamsModeEquals(params, givenParams);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        controller.setPlaylistParams(params);
-
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        ensurePlaylistParamsModeEquals(params, mSession.getPlaylistParams());
-        ensurePlaylistParamsModeEquals(params, controller.getPlaylistParams());
-    }
-
-    @Test
-    public void testSetVolumeTo() throws Exception {
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        TestVolumeProvider volumeProvider =
-                new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
-
-        mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
-        final MediaController2 controller = createController(mSession.getToken(), true, null);
-
-        final int targetVolume = 50;
-        controller.setVolumeTo(targetVolume, 0 /* flags */);
-        assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(volumeProvider.mSetVolumeToCalled);
-        assertEquals(targetVolume, volumeProvider.mVolume);
-    }
-
-    @Test
-    public void testAdjustVolume() throws Exception {
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        TestVolumeProvider volumeProvider =
-                new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
-
-        mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
-        final MediaController2 controller = createController(mSession.getToken(), true, null);
-
-        final int direction = AudioManager.ADJUST_RAISE;
-        controller.adjustVolume(direction, 0 /* flags */);
-        assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(volumeProvider.mAdjustVolumeCalled);
-        assertEquals(direction, volumeProvider.mDirection);
-    }
-
-    @Test
-    public void testGetPackageName() {
-        assertEquals(mContext.getPackageName(), mController.getSessionToken().getPackageName());
-    }
-
-    // This also tests getPlaybackState().
-    @Ignore
-    @Test
-    public void testControllerCallback_onPlaybackStateChanged() throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                // Called only once when the player's playback state is changed after this.
-                assertEquals(PlaybackState2.STATE_PAUSED, state.getState());
-                latch.countDown();
-            }
-        };
-        mPlayer.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PLAYING));
-        mController = createController(mSession.getToken(), true, callback);
-        assertEquals(PlaybackState2.STATE_PLAYING, mController.getPlaybackState().getState());
-        mPlayer.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertEquals(PlaybackState2.STATE_PAUSED, mController.getPlaybackState().getState());
-    }
-
-    @Test
-    public void testSendCustomCommand() throws InterruptedException {
-        // TODO(jaewan): Need to revisit with the permission.
-        final Command testCommand =
-                new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
-        final Bundle testArgs = new Bundle();
-        testArgs.putString("args", "testSendCustomAction");
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onCustomCommand(MediaSession2 session, ControllerInfo controller,
-                    Command customCommand, Bundle args, ResultReceiver cb) {
-                super.onCustomCommand(session, controller, customCommand, args, cb);
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(testCommand, customCommand);
-                assertTrue(TestUtils.equals(testArgs, args));
-                assertNull(cb);
-                latch.countDown();
-            }
-        };
-        mSession.close();
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback).setId(TAG).build();
-        final MediaController2 controller = createController(mSession.getToken());
-        controller.sendCustomCommand(testCommand, testArgs, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testControllerCallback_onConnected() throws InterruptedException {
-        // createController() uses controller callback to wait until the controller becomes
-        // available.
-        MediaController2 controller = createController(mSession.getToken());
-        assertNotNull(controller);
-    }
-
-    @Test
-    public void testControllerCallback_sessionRejects() throws InterruptedException {
-        final MediaSession2.SessionCallback sessionCallback = new SessionCallback(mContext) {
-            @Override
-            public MediaSession2.CommandGroup onConnect(MediaSession2 session,
-                    ControllerInfo controller) {
-                return null;
-            }
-        };
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, sessionCallback).build();
-        });
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        assertNotNull(controller);
-        waitForConnect(controller, false);
-        waitForDisconnect(controller, true);
-    }
-
-    @Test
-    public void testControllerCallback_releaseSession() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-        });
-        waitForDisconnect(mController, true);
-    }
-
-    @Test
-    public void testControllerCallback_release() throws InterruptedException {
-        mController.close();
-        waitForDisconnect(mController, true);
-    }
-
-    @Test
-    public void testPlayFromSearch() throws InterruptedException {
-        final String request = "random query";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromSearch(MediaSession2 session, ControllerInfo controller,
-                    String query, Bundle extras) {
-                super.onPlayFromSearch(session, controller, query, extras);
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, query);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromSearch").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromSearch(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPlayFromUri() throws InterruptedException {
-        final Uri request = Uri.parse("foo://boo");
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
-                    Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, uri);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromUri").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromUri(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPlayFromMediaId() throws InterruptedException {
-        final String request = "media_id";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromMediaId(MediaSession2 session, ControllerInfo controller,
-                    String mediaId, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, mediaId);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromMediaId").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromMediaId(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-
-    @Test
-    public void testPrepareFromSearch() throws InterruptedException {
-        final String request = "random query";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromSearch(MediaSession2 session, ControllerInfo controller,
-                    String query, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, query);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromSearch").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromSearch(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPrepareFromUri() throws InterruptedException {
-        final Uri request = Uri.parse("foo://boo");
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
-                    Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, uri);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromUri").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromUri(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPrepareFromMediaId() throws InterruptedException {
-        final String request = "media_id";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromMediaId(MediaSession2 session, ControllerInfo controller,
-                    String mediaId, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, mediaId);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromMediaId").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromMediaId(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testSetRating() throws InterruptedException {
-        final int ratingType = Rating2.RATING_5_STARS;
-        final float ratingValue = 3.5f;
-        final Rating2 rating = Rating2.newStarRating(mContext, ratingType, ratingValue);
-        final String mediaId = "media_id";
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onSetRating(MediaSession2 session, ControllerInfo controller,
-                    String mediaIdOut, Rating2 ratingOut) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(mediaId, mediaIdOut);
-                assertEquals(rating, ratingOut);
-                latch.countDown();
-            }
-        };
-
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testSetRating").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.setRating(mediaId, rating);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testIsConnected() throws InterruptedException {
-        assertTrue(mController.isConnected());
-        sHandler.postAndSync(()->{
-            mSession.close();
-        });
-        // postAndSync() to wait until the disconnection is propagated.
-        sHandler.postAndSync(()->{
-            assertFalse(mController.isConnected());
-        });
-    }
-
-    /**
-     * Test potential deadlock for calls between controller and session.
-     */
-    @Test
-    public void testDeadlock() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = null;
-        });
-
-        // Two more threads are needed not to block test thread nor test wide thread (sHandler).
-        final HandlerThread sessionThread = new HandlerThread("testDeadlock_session");
-        final HandlerThread testThread = new HandlerThread("testDeadlock_test");
-        sessionThread.start();
-        testThread.start();
-        final SyncHandler sessionHandler = new SyncHandler(sessionThread.getLooper());
-        final Handler testHandler = new Handler(testThread.getLooper());
-        final CountDownLatch latch = new CountDownLatch(1);
-        try {
-            final MockPlayer player = new MockPlayer(0);
-            sessionHandler.postAndSync(() -> {
-                mSession = new MediaSession2.Builder(mContext)
-                        .setPlayer(mPlayer)
-                        .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                        .setId("testDeadlock").build();
-            });
-            final MediaController2 controller = createController(mSession.getToken());
-            testHandler.post(() -> {
-                final PlaybackState2 state = createPlaybackState(PlaybackState2.STATE_ERROR);
-                for (int i = 0; i < 100; i++) {
-                    // triggers call from session to controller.
-                    player.notifyPlaybackState(state);
-                    // triggers call from controller to session.
-                    controller.play();
-
-                    // Repeat above
-                    player.notifyPlaybackState(state);
-                    controller.pause();
-                    player.notifyPlaybackState(state);
-                    controller.stop();
-                    player.notifyPlaybackState(state);
-                    controller.skipToNextItem();
-                    player.notifyPlaybackState(state);
-                    controller.skipToPreviousItem();
-                }
-                // This may hang if deadlock happens.
-                latch.countDown();
-            });
-            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } finally {
-            if (mSession != null) {
-                sessionHandler.postAndSync(() -> {
-                    // Clean up here because sessionHandler will be removed afterwards.
-                    mSession.close();
-                    mSession = null;
-                });
-            }
-            if (sessionThread != null) {
-                sessionThread.quitSafely();
-            }
-            if (testThread != null) {
-                testThread.quitSafely();
-            }
-        }
-    }
-
-    @Test
-    public void testGetServiceToken() {
-        SessionToken2 token = TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID);
-        assertNotNull(token);
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(MockMediaSessionService2.ID, token.getId());
-        assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-    }
-
-    @Test
-    public void testConnectToService_sessionService() throws InterruptedException {
-        testConnectToService(MockMediaSessionService2.ID);
-    }
-
-    @Ignore
-    @Test
-    public void testConnectToService_libraryService() throws InterruptedException {
-        testConnectToService(MockMediaLibraryService2.ID);
-    }
-
-    public void testConnectToService(String id) throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public CommandGroup onConnect(@NonNull MediaSession2 session,
-                    @NonNull ControllerInfo controller) {
-                if (Process.myUid() == controller.getUid()) {
-                    if (mSession != null) {
-                        mSession.close();
-                    }
-                    mSession = session;
-                    mPlayer = (MockPlayer) session.getPlayer();
-                    assertEquals(mContext.getPackageName(), controller.getPackageName());
-                    assertFalse(controller.isTrusted());
-                    latch.countDown();
-                }
-                return super.onConnect(session, controller);
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy);
-
-        mController = createController(TestUtils.getServiceToken(mContext, id));
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Test command from controller to session service
-        mController.play();
-        assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertTrue(mPlayer.mPlayCalled);
-
-        // Test command from session service to controller
-        // TODO(jaewan): Add equivalent tests again
-        /*
-        final CountDownLatch latch = new CountDownLatch(1);
-        mController.registerPlayerEventCallback((state) -> {
-            assertNotNull(state);
-            assertEquals(PlaybackState.STATE_REWINDING, state.getState());
-            latch.countDown();
-        }, sHandler);
-        mPlayer.notifyPlaybackState(
-                TestUtils.createPlaybackState(PlaybackState.STATE_REWINDING));
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        */
-    }
-
-    @Test
-    public void testControllerAfterSessionIsGone_session() throws InterruptedException {
-        testControllerAfterSessionIsGone(mSession.getToken().getId());
-    }
-
-    // TODO(jaewan): Re-enable this test
-    @Ignore
-    @Test
-    public void testControllerAfterSessionIsGone_sessionService() throws InterruptedException {
-        /*
-        connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID));
-        testControllerAfterSessionIsGone(MockMediaSessionService2.ID);
-        */
-    }
-
-    @Test
-    public void testClose_beforeConnected() throws InterruptedException {
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        controller.close();
-    }
-
-    @Test
-    public void testClose_twice() throws InterruptedException {
-        mController.close();
-        mController.close();
-    }
-
-    @Test
-    public void testClose_session() throws InterruptedException {
-        final String id = mSession.getToken().getId();
-        mController.close();
-        // close is done immediately for session.
-        testNoInteraction();
-
-        // Test whether the controller is notified about later close of the session or
-        // re-creation.
-        testControllerAfterSessionIsGone(id);
-    }
-
-    @Test
-    public void testClose_sessionService() throws InterruptedException {
-        testCloseFromService(MockMediaSessionService2.ID);
-    }
-
-    @Test
-    public void testClose_libraryService() throws InterruptedException {
-        testCloseFromService(MockMediaLibraryService2.ID);
-    }
-
-    private void testCloseFromService(String id) throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onServiceDestroyed() {
-                latch.countDown();
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy);
-        mController = createController(TestUtils.getServiceToken(mContext, id));
-        mController.close();
-        // Wait until close triggers onDestroy() of the session service.
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertNull(TestServiceRegistry.getInstance().getServiceInstance());
-        testNoInteraction();
-
-        // Test whether the controller is notified about later close of the session or
-        // re-creation.
-        testControllerAfterSessionIsGone(id);
-    }
-
-    private void testControllerAfterSessionIsGone(final String id) throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            // TODO(jaewan): Use Session.close later when we add the API.
-            mSession.close();
-        });
-        waitForDisconnect(mController, true);
-        testNoInteraction();
-
-        // Ensure that the controller cannot use newly create session with the same ID.
-        sHandler.postAndSync(() -> {
-            // Recreated session has different session stub, so previously created controller
-            // shouldn't be available.
-            mSession = new MediaSession2.Builder(mContext)
-                    .setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                    .setId(id).build();
-        });
-        testNoInteraction();
-    }
-
-    private void testNoInteraction() throws InterruptedException {
-        // TODO: Uncomment
-        /*
-        final CountDownLatch latch = new CountDownLatch(1);
-        final PlayerEventCallback callback = new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                fail("Controller shouldn't be notified about change in session after the close.");
-                latch.countDown();
-            }
-        };
-        */
-
-        // TODO(jaewan): Add equivalent tests again
-        /*
-        mController.registerPlayerEventCallback(playbackListener, sHandler);
-        mPlayer.notifyPlaybackState(TestUtils.createPlaybackState(PlaybackState.STATE_BUFFERING));
-        assertFalse(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        mController.unregisterPlayerEventCallback(playbackListener);
-        */
-    }
-
-    // TODO(jaewan): Add  test for service connect rejection, when we differentiate session
-    //               active/inactive and connection accept/refuse
-
-    class TestVolumeProvider extends VolumeProvider2 {
-        final CountDownLatch mLatch = new CountDownLatch(1);
-        boolean mSetVolumeToCalled;
-        boolean mAdjustVolumeCalled;
-        int mVolume;
-        int mDirection;
-
-        public TestVolumeProvider(Context context, int controlType, int maxVolume,
-                int currentVolume) {
-            super(context, controlType, maxVolume, currentVolume);
-        }
-
-        @Override
-        public void onSetVolumeTo(int volume) {
-            mSetVolumeToCalled = true;
-            mVolume = volume;
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onAdjustVolume(int direction) {
-            mAdjustVolumeCalled = true;
-            mDirection = direction;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java b/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java
deleted file mode 100644
index 06b51bd..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import android.content.Context;
-import android.media.MediaMetadata2.Builder;
-import android.os.Bundle;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaMetadata2Test {
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    public void testBuilder() {
-        final Bundle extras = new Bundle();
-        extras.putString("MediaMetadata2Test", "testBuilder");
-        final String title = "title";
-        final long discNumber = 10;
-        final Rating2 rating = Rating2.newThumbRating(mContext, true);
-
-        MediaMetadata2.Builder builder = new Builder(mContext);
-        builder.setExtras(extras);
-        builder.putString(MediaMetadata2.METADATA_KEY_DISPLAY_TITLE, title);
-        builder.putLong(MediaMetadata2.METADATA_KEY_DISC_NUMBER, discNumber);
-        builder.putRating(MediaMetadata2.METADATA_KEY_USER_RATING, rating);
-
-        MediaMetadata2 metadata = builder.build();
-        assertTrue(TestUtils.equals(extras, metadata.getExtras()));
-        assertEquals(title, metadata.getString(MediaMetadata2.METADATA_KEY_DISPLAY_TITLE));
-        assertEquals(discNumber, metadata.getLong(MediaMetadata2.METADATA_KEY_DISC_NUMBER));
-        assertEquals(rating, metadata.getRating(MediaMetadata2.METADATA_KEY_USER_RATING));
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2Test.java b/packages/MediaComponents/test/src/android/media/MediaSession2Test.java
deleted file mode 100644
index a0b1f18..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2Test.java
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static android.media.AudioAttributes.CONTENT_TYPE_MUSIC;
-import static android.media.TestUtils.ensurePlaylistParamsModeEquals;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.media.MediaController2.PlaybackInfo;
-import android.media.MediaSession2.Builder;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.MediaSession2.SessionCallback;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.annotation.NonNull;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests {@link MediaSession2}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaSession2Test extends MediaSession2TestBase {
-    private static final String TAG = "MediaSession2Test";
-
-    private MediaSession2 mSession;
-    private MockPlayer mPlayer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mPlayer = new MockPlayer(0);
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {}).build();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        mSession.close();
-    }
-
-    @Ignore
-    @Test
-    public void testBuilder() throws Exception {
-        try {
-            MediaSession2.Builder builder = new Builder(mContext);
-            fail("null player shouldn't be allowed");
-        } catch (IllegalArgumentException e) {
-            // expected. pass-through
-        }
-        MediaSession2.Builder builder = new Builder(mContext).setPlayer(mPlayer);
-        try {
-            builder.setId(null);
-            fail("null id shouldn't be allowed");
-        } catch (IllegalArgumentException e) {
-            // expected. pass-through
-        }
-    }
-
-    @Test
-    public void testUpdatePlayer() throws Exception {
-        MockPlayer player = new MockPlayer(0);
-        // Test if setPlayer doesn't crash with various situations.
-        mSession.updatePlayer(mPlayer, null, null);
-        mSession.updatePlayer(player, null, null);
-        mSession.close();
-    }
-
-    @Test
-    public void testSetPlayer_playbackInfo() throws Exception {
-        MockPlayer player = new MockPlayer(0);
-        AudioAttributes attrs = new AudioAttributes.Builder()
-                .setContentType(CONTENT_TYPE_MUSIC)
-                .build();
-        player.setAudioAttributes(attrs);
-
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        VolumeProvider2 volumeProvider =
-                new VolumeProvider2(mContext, volumeControlType, maxVolume, currentVolume) { };
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaybackInfoChanged(PlaybackInfo info) {
-                assertEquals(MediaController2.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
-                        info.getPlaybackType());
-                assertEquals(attrs, info.getAudioAttributes());
-                assertEquals(volumeControlType, info.getPlaybackType());
-                assertEquals(maxVolume, info.getMaxVolume());
-                assertEquals(currentVolume, info.getCurrentVolume());
-                latch.countDown();
-            }
-        };
-
-        mSession.updatePlayer(player, null, null);
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        PlaybackInfo info = controller.getPlaybackInfo();
-        assertNotNull(info);
-        assertEquals(PlaybackInfo.PLAYBACK_TYPE_LOCAL, info.getPlaybackType());
-        assertEquals(attrs, info.getAudioAttributes());
-        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int localVolumeControlType = manager.isVolumeFixed()
-                ? VolumeProvider2.VOLUME_CONTROL_FIXED : VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        assertEquals(localVolumeControlType, info.getControlType());
-        assertEquals(manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), info.getMaxVolume());
-        assertEquals(manager.getStreamVolume(AudioManager.STREAM_MUSIC), info.getCurrentVolume());
-
-        mSession.updatePlayer(player, null, volumeProvider);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-
-        info = controller.getPlaybackInfo();
-        assertNotNull(info);
-        assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
-        assertEquals(attrs, info.getAudioAttributes());
-        assertEquals(volumeControlType, info.getControlType());
-        assertEquals(maxVolume, info.getMaxVolume());
-        assertEquals(currentVolume, info.getCurrentVolume());
-    }
-
-    @Test
-    public void testPlay() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.play();
-            assertTrue(mPlayer.mPlayCalled);
-        });
-    }
-
-    @Test
-    public void testPause() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.pause();
-            assertTrue(mPlayer.mPauseCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testStop() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.stop();
-            assertTrue(mPlayer.mStopCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToNextItem() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.skipToNextItem();
-            assertTrue(mPlayer.mSkipToNextCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToPreviousItem() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.skipToPreviousItem();
-            assertTrue(mPlayer.mSkipToPreviousCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testSetPlaylist() throws Exception {
-        final List<MediaItem2> playlist = new ArrayList<>();
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistChanged(List<MediaItem2> givenList) {
-                assertMediaItemListEquals(playlist, givenList);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        mSession.setPlaylist(playlist);
-
-        assertTrue(mPlayer.mSetPlaylistCalled);
-        assertMediaItemListEquals(playlist, mPlayer.mPlaylist);
-        assertMediaItemListEquals(playlist, mSession.getPlaylist());
-
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertMediaItemListEquals(playlist, controller.getPlaylist());
-    }
-
-    @Ignore
-    @Test
-    public void testSetPlaylistParams() throws Exception {
-        final PlaylistParams params = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL,
-                PlaylistParams.SHUFFLE_MODE_ALL,
-                null /* PlaylistMetadata */);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistParamsChanged(PlaylistParams givenParams) {
-                ensurePlaylistParamsModeEquals(params, givenParams);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        mSession.setPlaylistParams(params);
-        assertTrue(mPlayer.mSetPlaylistParamsCalled);
-        ensurePlaylistParamsModeEquals(params, mPlayer.mPlaylistParams);
-        ensurePlaylistParamsModeEquals(params, mSession.getPlaylistParams());
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testRegisterEventCallback() throws InterruptedException {
-        final int testWhat = 1001;
-        final MockPlayer player = new MockPlayer(0);
-        final CountDownLatch playbackLatch = new CountDownLatch(3);
-        final CountDownLatch errorLatch = new CountDownLatch(1);
-        // TODO: Uncomment or remove
-        /*
-        final PlayerEventCallback callback = new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                assertEquals(sHandler.getLooper(), Looper.myLooper());
-                switch ((int) playbackLatch.getCount()) {
-                    case 3:
-                        assertNull(state);
-                        break;
-                    case 2:
-                        assertNotNull(state);
-                        assertEquals(PlaybackState2.STATE_PLAYING, state.getState());
-                        break;
-                    case 1:
-                        assertNotNull(state);
-                        assertEquals(PlaybackState2.STATE_PAUSED, state.getState());
-                        break;
-                    case 0:
-                        fail();
-                }
-                playbackLatch.countDown();
-            }
-
-            @Override
-            public void onError(String mediaId, int what, int extra) {
-                assertEquals(testWhat, what);
-                errorLatch.countDown();
-            }
-        };
-        */
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PLAYING));
-        // EventCallback will be notified with the mPlayer's playback state (null)
-        // TODO: Uncomment or remove
-        //mSession.registerPlayerEventCallback(sHandlerExecutor, callback);
-        // When the player is set, EventCallback will be notified about the new player's state.
-        mSession.updatePlayer(player, null, null);
-        // When the player is set, EventCallback will be notified about the new player's state.
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertTrue(playbackLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        player.notifyError(testWhat);
-        assertTrue(errorLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testBadPlayer() throws InterruptedException {
-        // TODO(jaewan): Add equivalent tests again
-        final CountDownLatch latch = new CountDownLatch(4); // expected call + 1
-        final BadPlayer player = new BadPlayer(0);
-        // TODO: Uncomment or remove
-        /*
-        mSession.registerPlayerEventCallback(sHandlerExecutor, new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                // This will be called for every setPlayer() calls, but no more.
-                assertNull(state);
-                latch.countDown();
-            }
-        });
-        */
-        mSession.updatePlayer(player, null, null);
-        mSession.updatePlayer(mPlayer, null, null);
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    private static class BadPlayer extends MockPlayer {
-        public BadPlayer(int count) {
-            super(count);
-        }
-
-        @Override
-        public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback listener) {
-            // No-op. This bad player will keep push notification to the listener that is previously
-            // registered by session.setPlayer().
-        }
-    }
-
-    @Test
-    public void testOnCommandCallback() throws InterruptedException {
-        final MockOnCommandCallback callback = new MockOnCommandCallback();
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mPlayer = new MockPlayer(1);
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, callback).build();
-        });
-        MediaController2 controller = createController(mSession.getToken());
-        controller.pause();
-        assertFalse(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertFalse(mPlayer.mPauseCalled);
-        assertEquals(1, callback.commands.size());
-        assertEquals(MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE,
-                (long) callback.commands.get(0).getCommandCode());
-        // TODO(jaewan): uncomment followings once skipToNextItem is implemented (b/74090741)
-//        controller.skipToNextItem();
-//        assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-//        assertTrue(mPlayer.mSkipToNextCalled);
-//        assertFalse(mPlayer.mPauseCalled);
-//        assertEquals(2, callback.commands.size());
-//        assertEquals(MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM,
-//                (long) callback.commands.get(1).getCommandCode());
-    }
-
-    @Test
-    public void testOnConnectCallback() throws InterruptedException {
-        final MockOnConnectCallback sessionCallback = new MockOnConnectCallback();
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, sessionCallback).build();
-        });
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        assertNotNull(controller);
-        waitForConnect(controller, false);
-        waitForDisconnect(controller, true);
-    }
-
-    @Test
-    public void testSetCustomLayout() throws InterruptedException {
-        final List<CommandButton> buttons = new ArrayList<>();
-        buttons.add(new CommandButton.Builder(mContext)
-                .setCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PLAY))
-                .setDisplayName("button").build());
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback sessionCallback = new SessionCallback(mContext) {
-            @Override
-            public CommandGroup onConnect(MediaSession2 session,
-                    ControllerInfo controller) {
-                if (mContext.getPackageName().equals(controller.getPackageName())) {
-                    mSession.setCustomLayout(controller, buttons);
-                }
-                return super.onConnect(session, controller);
-            }
-        };
-
-        try (final MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setId("testSetCustomLayout")
-                .setSessionCallback(sHandlerExecutor, sessionCallback)
-                .build()) {
-            if (mSession != null) {
-                mSession.close();
-                mSession = session;
-            }
-            final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-                @Override
-                public void onCustomLayoutChanged(List<CommandButton> layout) {
-                    assertEquals(layout.size(), buttons.size());
-                    for (int i = 0; i < layout.size(); i++) {
-                        assertEquals(layout.get(i).getCommand(), buttons.get(i).getCommand());
-                        assertEquals(layout.get(i).getDisplayName(),
-                                buttons.get(i).getDisplayName());
-                    }
-                    latch.countDown();
-                }
-            };
-            final MediaController2 controller =
-                    createController(session.getToken(), true, callback);
-            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testSetAllowedCommands() throws InterruptedException {
-        final CommandGroup commands = new CommandGroup(mContext);
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PLAY));
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE));
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_STOP));
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onAllowedCommandsChanged(CommandGroup commandsOut) {
-                assertNotNull(commandsOut);
-                List<Command> expected = commands.getCommands();
-                List<Command> actual = commandsOut.getCommands();
-
-                assertNotNull(actual);
-                assertEquals(expected.size(), actual.size());
-                for (int i = 0; i < expected.size(); i++) {
-                    assertEquals(expected.get(i), actual.get(i));
-                }
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        ControllerInfo controllerInfo = getTestControllerInfo();
-        assertNotNull(controllerInfo);
-
-        mSession.setAllowedCommands(controllerInfo, commands);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSendCustomAction() throws InterruptedException {
-        final Command testCommand =
-                new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
-        final Bundle testArgs = new Bundle();
-        testArgs.putString("args", "testSendCustomAction");
-
-        final CountDownLatch latch = new CountDownLatch(2);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onCustomCommand(Command command, Bundle args, ResultReceiver receiver) {
-                assertEquals(testCommand, command);
-                assertTrue(TestUtils.equals(testArgs, args));
-                assertNull(receiver);
-                latch.countDown();
-            }
-        };
-        final MediaController2 controller =
-                createController(mSession.getToken(), true, callback);
-        // TODO(jaewan): Test with multiple controllers
-        mSession.sendCustomCommand(testCommand, testArgs);
-
-        ControllerInfo controllerInfo = getTestControllerInfo();
-        assertNotNull(controllerInfo);
-        // TODO(jaewan): Test receivers as well.
-        mSession.sendCustomCommand(controllerInfo, testCommand, testArgs, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    private ControllerInfo getTestControllerInfo() {
-        List<ControllerInfo> controllers = mSession.getConnectedControllers();
-        assertNotNull(controllers);
-        for (int i = 0; i < controllers.size(); i++) {
-            if (Process.myUid() == controllers.get(i).getUid()) {
-                return controllers.get(i);
-            }
-        }
-        fail("Failed to get test controller info");
-        return null;
-    }
-
-    public class MockOnConnectCallback extends SessionCallback {
-        public MockOnConnectCallback() {
-            super(mContext);
-        }
-
-        @Override
-        public MediaSession2.CommandGroup onConnect(MediaSession2 session,
-                ControllerInfo controllerInfo) {
-            if (Process.myUid() != controllerInfo.getUid()) {
-                return null;
-            }
-            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
-            assertEquals(Process.myUid(), controllerInfo.getUid());
-            assertFalse(controllerInfo.isTrusted());
-            // Reject all
-            return null;
-        }
-    }
-
-    public class MockOnCommandCallback extends SessionCallback {
-        public final ArrayList<MediaSession2.Command> commands = new ArrayList<>();
-
-        public MockOnCommandCallback() {
-            super(mContext);
-        }
-
-        @Override
-        public boolean onCommandRequest(MediaSession2 session, ControllerInfo controllerInfo,
-                MediaSession2.Command command) {
-            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
-            assertEquals(Process.myUid(), controllerInfo.getUid());
-            assertFalse(controllerInfo.isTrusted());
-            commands.add(command);
-            if (command.getCommandCode() == MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    private static void assertMediaItemListEquals(List<MediaItem2> a, List<MediaItem2> b) {
-        if (a == null || b == null) {
-            assertEquals(a, b);
-        }
-        assertEquals(a.size(), b.size());
-
-        for (int i = 0; i < a.size(); i++) {
-            MediaItem2 aItem = a.get(i);
-            MediaItem2 bItem = b.get(i);
-
-            if (aItem == null || bItem == null) {
-                assertEquals(aItem, bItem);
-                continue;
-            }
-
-            assertEquals(aItem.getMediaId(), bItem.getMediaId());
-            assertEquals(aItem.getFlags(), bItem.getFlags());
-            TestUtils.equals(aItem.getMetadata().toBundle(), bItem.getMetadata().toBundle());
-
-            // Note: Here it does not check whether DataSourceDesc are equal,
-            // since there DataSourceDec is not comparable.
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java b/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java
deleted file mode 100644
index 83706c0..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.content.Context;
-import android.media.MediaController2.ControllerCallback;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.os.Bundle;
-import android.os.HandlerThread;
-import android.os.ResultReceiver;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-/**
- * Base class for session test.
- */
-abstract class MediaSession2TestBase {
-    // Expected success
-    static final int WAIT_TIME_MS = 1000;
-
-    // Expected timeout
-    static final int TIMEOUT_MS = 500;
-
-    static TestUtils.SyncHandler sHandler;
-    static Executor sHandlerExecutor;
-
-    Context mContext;
-    private List<MediaController2> mControllers = new ArrayList<>();
-
-    interface TestControllerInterface {
-        ControllerCallback getCallback();
-    }
-
-    // Any change here should be also reflected to the TestControllerCallback and
-    // TestBrowserCallback
-    interface TestControllerCallbackInterface {
-        // Add methods in ControllerCallback that you want to test.
-        default void onPlaylistChanged(List<MediaItem2> playlist) {}
-        default void onPlaylistParamsChanged(MediaSession2.PlaylistParams params) {}
-        default void onPlaybackInfoChanged(MediaController2.PlaybackInfo info) {}
-        default void onPlaybackStateChanged(PlaybackState2 state) {}
-        default void onCustomLayoutChanged(List<CommandButton> layout) {}
-        default void onAllowedCommandsChanged(CommandGroup commands) {}
-        default void onCustomCommand(Command command, Bundle args, ResultReceiver receiver) {}
-    }
-
-    interface WaitForConnectionInterface {
-        void waitForConnect(boolean expect) throws InterruptedException;
-        void waitForDisconnect(boolean expect) throws InterruptedException;
-    }
-
-    @BeforeClass
-    public static void setUpThread() {
-        if (sHandler == null) {
-            HandlerThread handlerThread = new HandlerThread("MediaSession2TestBase");
-            handlerThread.start();
-            sHandler = new TestUtils.SyncHandler(handlerThread.getLooper());
-            sHandlerExecutor = (runnable) -> {
-                sHandler.post(runnable);
-            };
-        }
-    }
-
-    @AfterClass
-    public static void cleanUpThread() {
-        if (sHandler != null) {
-            sHandler.getLooper().quitSafely();
-            sHandler = null;
-            sHandlerExecutor = null;
-        }
-    }
-
-    @CallSuper
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @CallSuper
-    public void cleanUp() throws Exception {
-        for (int i = 0; i < mControllers.size(); i++) {
-            mControllers.get(i).close();
-        }
-    }
-
-    /**
-     * Creates a {@link android.media.session.PlaybackState} with the given state.
-     *
-     * @param state one of the PlaybackState.STATE_xxx.
-     * @return a PlaybackState
-     */
-    public PlaybackState2 createPlaybackState(int state) {
-        return new PlaybackState2(mContext, state, 0, 0, 1.0f, 0, 0);
-    }
-
-    final MediaController2 createController(SessionToken2 token) throws InterruptedException {
-        return createController(token, true, null);
-    }
-
-    final MediaController2 createController(@NonNull SessionToken2 token,
-            boolean waitForConnect, @Nullable TestControllerCallbackInterface callback)
-            throws InterruptedException {
-        TestControllerInterface instance = onCreateController(token, callback);
-        if (!(instance instanceof MediaController2)) {
-            throw new RuntimeException("Test has a bug. Expected MediaController2 but returned "
-                    + instance);
-        }
-        MediaController2 controller = (MediaController2) instance;
-        mControllers.add(controller);
-        if (waitForConnect) {
-            waitForConnect(controller, true);
-        }
-        return controller;
-    }
-
-    private static WaitForConnectionInterface getWaitForConnectionInterface(
-            MediaController2 controller) {
-        if (!(controller instanceof TestControllerInterface)) {
-            throw new RuntimeException("Test has a bug. Expected controller implemented"
-                    + " TestControllerInterface but got " + controller);
-        }
-        ControllerCallback callback = ((TestControllerInterface) controller).getCallback();
-        if (!(callback instanceof WaitForConnectionInterface)) {
-            throw new RuntimeException("Test has a bug. Expected controller with callback "
-                    + " implemented WaitForConnectionInterface but got " + controller);
-        }
-        return (WaitForConnectionInterface) callback;
-    }
-
-    public static void waitForConnect(MediaController2 controller, boolean expected)
-            throws InterruptedException {
-        getWaitForConnectionInterface(controller).waitForConnect(expected);
-    }
-
-    public static void waitForDisconnect(MediaController2 controller, boolean expected)
-            throws InterruptedException {
-        getWaitForConnectionInterface(controller).waitForDisconnect(expected);
-    }
-
-    TestControllerInterface onCreateController(@NonNull SessionToken2 token,
-            @Nullable TestControllerCallbackInterface callback) {
-        if (callback == null) {
-            callback = new TestControllerCallbackInterface() {};
-        }
-        return new TestMediaController(mContext, token, new TestControllerCallback(callback));
-    }
-
-    public static class TestControllerCallback extends MediaController2.ControllerCallback
-            implements WaitForConnectionInterface {
-        public final TestControllerCallbackInterface mCallbackProxy;
-        public final CountDownLatch connectLatch = new CountDownLatch(1);
-        public final CountDownLatch disconnectLatch = new CountDownLatch(1);
-
-        TestControllerCallback(@NonNull TestControllerCallbackInterface callbackProxy) {
-            if (callbackProxy == null) {
-                throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
-            }
-            mCallbackProxy = callbackProxy;
-        }
-
-        @CallSuper
-        @Override
-        public void onConnected(MediaController2 controller, CommandGroup commands) {
-            connectLatch.countDown();
-        }
-
-        @CallSuper
-        @Override
-        public void onDisconnected(MediaController2 controller) {
-            disconnectLatch.countDown();
-        }
-
-        @Override
-        public void onPlaybackStateChanged(MediaController2 controller, PlaybackState2 state) {
-            mCallbackProxy.onPlaybackStateChanged(state);
-        }
-
-        @Override
-        public void onCustomCommand(MediaController2 controller, Command command, Bundle args,
-                ResultReceiver receiver) {
-            mCallbackProxy.onCustomCommand(command, args, receiver);
-        }
-
-        @Override
-        public void waitForConnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(connectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(connectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void waitForDisconnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(disconnectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(disconnectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void onPlaylistChanged(MediaController2 controller, List<MediaItem2> params) {
-            mCallbackProxy.onPlaylistChanged(params);
-        }
-
-        @Override
-        public void onPlaylistParamsChanged(MediaController2 controller,
-                MediaSession2.PlaylistParams params) {
-            mCallbackProxy.onPlaylistParamsChanged(params);
-        }
-
-        @Override
-        public void onPlaybackInfoChanged(MediaController2 controller,
-                MediaController2.PlaybackInfo info) {
-            mCallbackProxy.onPlaybackInfoChanged(info);
-        }
-
-        @Override
-        public void onCustomLayoutChanged(MediaController2 controller, List<CommandButton> layout) {
-            mCallbackProxy.onCustomLayoutChanged(layout);
-        }
-
-        @Override
-        public void onAllowedCommandsChanged(MediaController2 controller, CommandGroup commands) {
-            mCallbackProxy.onAllowedCommandsChanged(commands);
-        }
-    }
-
-    public class TestMediaController extends MediaController2 implements TestControllerInterface {
-        private final ControllerCallback mCallback;
-
-        public TestMediaController(@NonNull Context context, @NonNull SessionToken2 token,
-                @NonNull ControllerCallback callback) {
-            super(context, token, sHandlerExecutor, callback);
-            mCallback = callback;
-        }
-
-        @Override
-        public ControllerCallback getCallback() {
-            return mCallback;
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java b/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java
deleted file mode 100644
index ca36513..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_FAST_FORWARD;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_PLAY;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_REWIND;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SEEK_TO;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_STOP;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_URI;
-import static android.media.MediaSession2.ControllerInfo;
-import static android.media.MediaSession2.PlaylistParams;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.SessionCallback;
-import android.net.Uri;
-import android.os.Process;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Tests whether {@link MediaSession2} receives commands that hasn't allowed.
- */
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class MediaSession2_PermissionTest extends MediaSession2TestBase {
-    private static final String SESSION_ID = "MediaSession2Test_permission";
-
-    private MockPlayer mPlayer;
-    private MediaSession2 mSession;
-    private MediaSession2.SessionCallback mCallback;
-
-    private MediaSession2 matchesSession() {
-        return argThat((session) -> session == mSession);
-    }
-
-    private static ControllerInfo matchesCaller() {
-        return argThat((controllerInfo) -> controllerInfo.getUid() == Process.myUid());
-    }
-
-    private static Command matches(final int commandCode) {
-        return argThat((command) -> command.getCommandCode() == commandCode);
-    }
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        if (mSession != null) {
-            mSession.close();
-            mSession = null;
-        }
-        mPlayer = null;
-        mCallback = null;
-    }
-
-    private MediaSession2 createSessionWithAllowedActions(CommandGroup commands) {
-        mPlayer = new MockPlayer(0);
-        if (commands == null) {
-            commands = new CommandGroup(mContext);
-        }
-        mCallback = mock(SessionCallback.class);
-        when(mCallback.onConnect(any(), any())).thenReturn(commands);
-        if (mSession != null) {
-            mSession.close();
-        }
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer).setId(SESSION_ID)
-                .setSessionCallback(sHandlerExecutor, mCallback).build();
-        return mSession;
-    }
-
-    private CommandGroup createCommandGroupWith(int commandCode) {
-        CommandGroup commands = new CommandGroup(mContext);
-        commands.addCommand(new Command(mContext, commandCode));
-        return commands;
-    }
-
-    private CommandGroup createCommandGroupWithout(int commandCode) {
-        CommandGroup commands = new CommandGroup(mContext);
-        commands.addAllPredefinedCommands();
-        commands.removeCommand(new Command(mContext, commandCode));
-        return commands;
-    }
-
-    @Test
-    public void testPlay() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_PLAY));
-        createController(mSession.getToken()).play();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_PLAY));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_PLAY));
-        createController(mSession.getToken()).play();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testPause() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_PAUSE));
-        createController(mSession.getToken()).pause();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_PAUSE));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_PAUSE));
-        createController(mSession.getToken()).pause();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testStop() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_STOP));
-        createController(mSession.getToken()).stop();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_STOP));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_STOP));
-        createController(mSession.getToken()).stop();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSkipToNext() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-        createController(mSession.getToken()).skipToNextItem();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-        createController(mSession.getToken()).skipToNextItem();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSkipToPrevious() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-        createController(mSession.getToken()).skipToPreviousItem();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-        createController(mSession.getToken()).skipToPreviousItem();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testFastForward() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-        createController(mSession.getToken()).fastForward();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-        createController(mSession.getToken()).fastForward();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testRewind() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_REWIND));
-        createController(mSession.getToken()).rewind();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_REWIND));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_REWIND));
-        createController(mSession.getToken()).rewind();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSeekTo() throws InterruptedException {
-        final long position = 10;
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SEEK_TO));
-        createController(mSession.getToken()).seekTo(position);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SEEK_TO));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SEEK_TO));
-        createController(mSession.getToken()).seekTo(position);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    // TODO(jaewan): Uncomment when we implement skipToPlaylistItem()
-    /*
-    @Test
-    public void testSkipToPlaylistItem() throws InterruptedException {
-        final Uri uri = Uri.parse("set://current.playlist.item");
-        final DataSourceDesc dsd = new DataSourceDesc.Builder()
-                .setDataSource(mContext, uri).build();
-        final MediaItem2 item = new MediaItem2.Builder(mContext, MediaItem2.FLAG_PLAYABLE)
-                .setDataSourceDesc(dsd).build();
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-        createController(mSession.getToken()).skipToPlaylistItem(item);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(matchesCaller(),
-                matches(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-        createController(mSession.getToken()).skipToPlaylistItem(item);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any());
-    }
-    */
-
-    @Test
-    public void testSetPlaylistParams() throws InterruptedException {
-        final PlaylistParams param = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL, PlaylistParams.SHUFFLE_MODE_ALL, null);
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-        createController(mSession.getToken()).setPlaylistParams(param);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(),
-                matches(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-        createController(mSession.getToken()).setPlaylistParams(param);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSetVolume() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-        createController(mSession.getToken()).setVolumeTo(0, 0);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-        createController(mSession.getToken()).setVolumeTo(0, 0);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromMediaId() throws InterruptedException {
-        final String mediaId = "testPlayFromMediaId";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_MEDIA_ID));
-        createController(mSession.getToken()).playFromMediaId(mediaId, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromMediaId(
-                matchesSession(), matchesCaller(), eq(mediaId), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_MEDIA_ID));
-        createController(mSession.getToken()).playFromMediaId(mediaId, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromMediaId(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromUri() throws InterruptedException {
-        final Uri uri = Uri.parse("play://from.uri");
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_URI));
-        createController(mSession.getToken()).playFromUri(uri, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromUri(
-                matchesSession(), matchesCaller(), eq(uri), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_URI));
-        createController(mSession.getToken()).playFromUri(uri, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromUri(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromSearch() throws InterruptedException {
-        final String query = "testPlayFromSearch";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_SEARCH));
-        createController(mSession.getToken()).playFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_SEARCH));
-        createController(mSession.getToken()).playFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromSearch(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromMediaId() throws InterruptedException {
-        final String mediaId = "testPrepareFromMediaId";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_MEDIA_ID));
-        createController(mSession.getToken()).prepareFromMediaId(mediaId, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromMediaId(
-                matchesSession(), matchesCaller(), eq(mediaId), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_MEDIA_ID));
-        createController(mSession.getToken()).prepareFromMediaId(mediaId, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromMediaId(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromUri() throws InterruptedException {
-        final Uri uri = Uri.parse("prepare://from.uri");
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_URI));
-        createController(mSession.getToken()).prepareFromUri(uri, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromUri(
-                matchesSession(), matchesCaller(), eq(uri), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_URI));
-        createController(mSession.getToken()).prepareFromUri(uri, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromUri(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromSearch() throws InterruptedException {
-        final String query = "testPrepareFromSearch";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        createController(mSession.getToken()).prepareFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        createController(mSession.getToken()).prepareFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromSearch(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testChangingPermissionWithSetAllowedCommands() throws InterruptedException {
-        final String query = "testChangingPermissionWithSetAllowedCommands";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_SEARCH));
-
-        TestControllerCallbackInterface controllerCallback =
-                mock(TestControllerCallbackInterface.class);
-        MediaController2 controller =
-                createController(mSession.getToken(), true, controllerCallback);
-
-        controller.prepareFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-        clearInvocations(mCallback);
-
-        // Change allowed commands.
-        mSession.setAllowedCommands(getTestControllerInfo(),
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        verify(controllerCallback, timeout(TIMEOUT_MS).atLeastOnce())
-                .onAllowedCommandsChanged(any());
-
-        controller.prepareFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromSearch(
-                any(), any(), any(), any());
-    }
-
-    private ControllerInfo getTestControllerInfo() {
-        List<ControllerInfo> controllers = mSession.getConnectedControllers();
-        assertNotNull(controllers);
-        for (int i = 0; i < controllers.size(); i++) {
-            if (Process.myUid() == controllers.get(i).getUid()) {
-                return controllers.get(i);
-            }
-        }
-        fail("Failed to get test controller info");
-        return null;
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java b/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
deleted file mode 100644
index 17b200f..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import android.content.Context;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
-import android.media.session.MediaSessionManager;
-import android.media.session.MediaSessionManager.OnSessionTokensChangedListener;
-import android.media.session.PlaybackState;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.UUID;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests {@link MediaSessionManager} with {@link MediaSession2} specific APIs.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaSessionManager_MediaSession2 extends MediaSession2TestBase {
-    private static final String TAG = "MediaSessionManager_MediaSession2";
-
-    private MediaSessionManager mManager;
-    private MediaSession2 mSession;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
-
-        // Specify TAG here so {@link MediaSession2.getInstance()} doesn't complaint about
-        // per test thread differs across the {@link MediaSession2} with the same TAG.
-        final MockPlayer player = new MockPlayer(1);
-        mSession = new MediaSession2.Builder(mContext)
-                .setPlayer(player)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) { })
-                .setId(TAG)
-                .build();
-        ensureChangeInSession();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        sHandler.removeCallbacksAndMessages(null);
-        mSession.close();
-    }
-
-    // TODO(jaewan): Make this host-side test to see per-user behavior.
-    @Ignore
-    @Test
-    public void testGetMediaSession2Tokens_hasMediaController() throws InterruptedException {
-        final MockPlayer player = (MockPlayer) mSession.getPlayer();
-        player.notifyPlaybackState(createPlaybackState(PlaybackState.STATE_STOPPED));
-
-        MediaController2 controller = null;
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        assertNotNull(tokens);
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId())) {
-                assertNull(controller);
-                controller = createController(token);
-            }
-        }
-        assertNotNull(controller);
-
-        // Test if the found controller is correct one.
-        assertEquals(PlaybackState.STATE_STOPPED, controller.getPlaybackState().getState());
-        controller.play();
-
-        assertTrue(player.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(player.mPlayCalled);
-    }
-
-    /**
-     * Test if server recognizes a session even if the session refuses the connection from server.
-     *
-     * @throws InterruptedException
-     */
-    @Test
-    public void testGetSessionTokens_sessionRejected() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(new MockPlayer(0))
-                    .setId(TAG).setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {
-                        @Override
-                        public MediaSession2.CommandGroup onConnect(
-                                MediaSession2 session, ControllerInfo controller) {
-                            // Reject all connection request.
-                            return null;
-                        }
-                    }).build();
-        });
-        ensureChangeInSession();
-
-        boolean foundSession = false;
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        assertNotNull(tokens);
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId())) {
-                assertFalse(foundSession);
-                foundSession = true;
-            }
-        }
-        assertTrue(foundSession);
-    }
-
-    @Test
-    public void testGetMediaSession2Tokens_playerRemoved() throws InterruptedException {
-        // Release
-        sHandler.postAndSync(() -> {
-            mSession.close();
-        });
-        ensureChangeInSession();
-
-        // When the mSession's player becomes null, it should lose binder connection between server.
-        // So server will forget the session.
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            assertFalse(mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId()));
-        }
-    }
-
-    @Test
-    public void testGetMediaSessionService2Token() throws InterruptedException {
-        boolean foundTestSessionService = false;
-        boolean foundTestLibraryService = false;
-        List<SessionToken2> tokens = mManager.getSessionServiceTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && MockMediaSessionService2.ID.equals(token.getId())) {
-                assertFalse(foundTestSessionService);
-                assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-                foundTestSessionService = true;
-            } else if (mContext.getPackageName().equals(token.getPackageName())
-                    && MockMediaLibraryService2.ID.equals(token.getId())) {
-                assertFalse(foundTestLibraryService);
-                assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-                foundTestLibraryService = true;
-            }
-        }
-        assertTrue(foundTestSessionService);
-        assertTrue(foundTestLibraryService);
-    }
-
-    @Test
-    public void testGetAllSessionTokens() throws InterruptedException {
-        boolean foundTestSession = false;
-        boolean foundTestSessionService = false;
-        boolean foundTestLibraryService = false;
-        List<SessionToken2> tokens = mManager.getAllSessionTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (!mContext.getPackageName().equals(token.getPackageName())) {
-                continue;
-            }
-            switch (token.getId()) {
-                case TAG:
-                    assertFalse(foundTestSession);
-                    foundTestSession = true;
-                    break;
-                case MockMediaSessionService2.ID:
-                    assertFalse(foundTestSessionService);
-                    foundTestSessionService = true;
-                    assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-                    break;
-                case MockMediaLibraryService2.ID:
-                    assertFalse(foundTestLibraryService);
-                    assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-                    foundTestLibraryService = true;
-                    break;
-                default:
-                    fail("Unexpected session " + token + " exists in the package");
-            }
-        }
-        assertTrue(foundTestSession);
-        assertTrue(foundTestSessionService);
-        assertTrue(foundTestLibraryService);
-    }
-
-    @Test
-    public void testAddOnSessionTokensChangedListener() throws InterruptedException {
-        TokensChangedListener listener = new TokensChangedListener();
-        mManager.addOnSessionTokensChangedListener(sHandlerExecutor, listener);
-
-        listener.reset();
-        MediaSession2 session1 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertTrue(listener.findToken(session1.getToken()));
-
-        listener.reset();
-        session1.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-
-        listener.reset();
-        MediaSession2 session2 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertTrue(listener.findToken(session2.getToken()));
-
-        listener.reset();
-        MediaSession2 session3 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertTrue(listener.findToken(session2.getToken()));
-        assertTrue(listener.findToken(session3.getToken()));
-
-        listener.reset();
-        session2.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertFalse(listener.findToken(session2.getToken()));
-        assertTrue(listener.findToken(session3.getToken()));
-
-        listener.reset();
-        session3.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertFalse(listener.findToken(session2.getToken()));
-        assertFalse(listener.findToken(session3.getToken()));
-
-        mManager.removeOnSessionTokensChangedListener(listener);
-    }
-
-    @Test
-    public void testRemoveOnSessionTokensChangedListener() throws InterruptedException {
-        TokensChangedListener listener = new TokensChangedListener();
-        mManager.addOnSessionTokensChangedListener(sHandlerExecutor, listener);
-
-        listener.reset();
-        MediaSession2 session1 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-
-        mManager.removeOnSessionTokensChangedListener(listener);
-
-        listener.reset();
-        session1.close();
-        assertFalse(listener.await());
-
-        listener.reset();
-        MediaSession2 session2 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertFalse(listener.await());
-
-        listener.reset();
-        MediaSession2 session3 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertFalse(listener.await());
-
-        listener.reset();
-        session2.close();
-        assertFalse(listener.await());
-
-        listener.reset();
-        session3.close();
-        assertFalse(listener.await());
-    }
-
-    // Ensures if the session creation/release is notified to the server.
-    private void ensureChangeInSession() throws InterruptedException {
-        // TODO(jaewan): Wait by listener.
-        Thread.sleep(WAIT_TIME_MS);
-    }
-
-    private class TokensChangedListener implements OnSessionTokensChangedListener {
-        private CountDownLatch mLatch;
-        private List<SessionToken2> mTokens;
-
-        private void reset() {
-            mLatch = new CountDownLatch(1);
-            mTokens = null;
-        }
-
-        private boolean await() throws InterruptedException {
-            return mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        }
-
-        private boolean findToken(SessionToken2 token) {
-            return mTokens.contains(token);
-        }
-
-        @Override
-        public void onSessionTokensChanged(List<SessionToken2> tokens) {
-            mTokens = tokens;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockActivity.java b/packages/MediaComponents/test/src/android/media/MockActivity.java
deleted file mode 100644
index 4627530..0000000
--- a/packages/MediaComponents/test/src/android/media/MockActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import android.app.Activity;
-
-public class MockActivity extends Activity {
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
deleted file mode 100644
index df516c5..0000000
--- a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
-* Copyright 2018 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;
-
-import static junit.framework.Assert.fail;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.Context;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-import java.util.List;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Mock implementation of {@link MediaLibraryService2} for testing.
- */
-public class MockMediaLibraryService2 extends MediaLibraryService2 {
-    // Keep in sync with the AndroidManifest.xml
-    public static final String ID = "TestLibrary";
-
-    public static final String ROOT_ID = "rootId";
-    public static final Bundle EXTRAS = new Bundle();
-
-    public static final String MEDIA_ID_GET_ITEM = "media_id_get_item";
-
-    public static final String PARENT_ID = "parent_id";
-    public static final String PARENT_ID_NO_CHILDREN = "parent_id_no_children";
-    public static final String PARENT_ID_ERROR = "parent_id_error";
-
-    public static final List<MediaItem2> GET_CHILDREN_RESULT = new ArrayList<>();
-    public static final int CHILDREN_COUNT = 100;
-
-    public static final String SEARCH_QUERY = "search_query";
-    public static final String SEARCH_QUERY_TAKES_TIME = "search_query_takes_time";
-    public static final int SEARCH_TIME_IN_MS = 5000;
-    public static final String SEARCH_QUERY_EMPTY_RESULT = "search_query_empty_result";
-
-    public static final List<MediaItem2> SEARCH_RESULT = new ArrayList<>();
-    public static final int SEARCH_RESULT_COUNT = 50;
-
-    private static final DataSourceDesc DATA_SOURCE_DESC =
-            new DataSourceDesc.Builder().setDataSource(new FileDescriptor()).build();
-
-    private static final String TAG = "MockMediaLibrarySvc2";
-
-    static {
-        EXTRAS.putString(ROOT_ID, ROOT_ID);
-    }
-    @GuardedBy("MockMediaLibraryService2.class")
-    private static SessionToken2 sToken;
-
-    private MediaLibrarySession mSession;
-
-    public MockMediaLibraryService2() {
-        super();
-        GET_CHILDREN_RESULT.clear();
-        String getChildrenMediaIdPrefix = "get_children_media_id_";
-        for (int i = 0; i < CHILDREN_COUNT; i++) {
-            GET_CHILDREN_RESULT.add(createMediaItem(getChildrenMediaIdPrefix + i));
-        }
-
-        SEARCH_RESULT.clear();
-        String getSearchResultMediaIdPrefix = "get_search_result_media_id_";
-        for (int i = 0; i < SEARCH_RESULT_COUNT; i++) {
-            SEARCH_RESULT.add(createMediaItem(getSearchResultMediaIdPrefix + i));
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        TestServiceRegistry.getInstance().setServiceInstance(this);
-        super.onCreate();
-    }
-
-    @Override
-    public MediaLibrarySession onCreateSession(String sessionId) {
-        final MockPlayer player = new MockPlayer(1);
-        final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler();
-        final Executor executor = (runnable) -> handler.post(runnable);
-        SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance()
-                .getSessionCallbackProxy();
-        if (sessionCallbackProxy == null) {
-            // Ensures non-null
-            sessionCallbackProxy = new SessionCallbackProxy(this) {};
-        }
-        TestLibrarySessionCallback callback =
-                new TestLibrarySessionCallback(sessionCallbackProxy);
-        mSession = new MediaLibrarySession.Builder(MockMediaLibraryService2.this, executor,
-                callback).setPlayer(player).setId(sessionId).build();
-        return mSession;
-    }
-
-    @Override
-    public void onDestroy() {
-        TestServiceRegistry.getInstance().cleanUp();
-        super.onDestroy();
-    }
-
-    public static SessionToken2 getToken(Context context) {
-        synchronized (MockMediaLibraryService2.class) {
-            if (sToken == null) {
-                sToken = new SessionToken2(context, context.getPackageName(),
-                        MockMediaLibraryService2.class.getName());
-                assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, sToken.getType());
-            }
-            return sToken;
-        }
-    }
-
-    private class TestLibrarySessionCallback extends MediaLibrarySessionCallback {
-        private final SessionCallbackProxy mCallbackProxy;
-
-        public TestLibrarySessionCallback(SessionCallbackProxy callbackProxy) {
-            super(MockMediaLibraryService2.this);
-            mCallbackProxy = callbackProxy;
-        }
-
-        @Override
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            return mCallbackProxy.onConnect(session, controller);
-        }
-
-        @Override
-        public LibraryRoot onGetLibraryRoot(MediaLibrarySession session, ControllerInfo controller,
-                Bundle rootHints) {
-            return new LibraryRoot(MockMediaLibraryService2.this, ROOT_ID, EXTRAS);
-        }
-
-        @Override
-        public MediaItem2 onGetItem(MediaLibrarySession session, ControllerInfo controller,
-                String mediaId) {
-            if (MEDIA_ID_GET_ITEM.equals(mediaId)) {
-                return createMediaItem(mediaId);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public List<MediaItem2> onGetChildren(MediaLibrarySession session,
-                ControllerInfo controller, String parentId, int page, int pageSize, Bundle extras) {
-            if (PARENT_ID.equals(parentId)) {
-                return getPaginatedResult(GET_CHILDREN_RESULT, page, pageSize);
-            } else if (PARENT_ID_ERROR.equals(parentId)) {
-                return null;
-            }
-            // Includes the case of PARENT_ID_NO_CHILDREN.
-            return new ArrayList<>();
-        }
-
-        @Override
-        public void onSearch(MediaLibrarySession session, ControllerInfo controllerInfo,
-                String query, Bundle extras) {
-            if (SEARCH_QUERY.equals(query)) {
-                mSession.notifySearchResultChanged(controllerInfo, query, SEARCH_RESULT_COUNT,
-                        extras);
-            } else if (SEARCH_QUERY_TAKES_TIME.equals(query)) {
-                // Searching takes some time. Notify after 5 seconds.
-                Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() {
-                    @Override
-                    public void run() {
-                        mSession.notifySearchResultChanged(
-                                controllerInfo, query, SEARCH_RESULT_COUNT, extras);
-                    }
-                }, SEARCH_TIME_IN_MS, TimeUnit.MILLISECONDS);
-            } else if (SEARCH_QUERY_EMPTY_RESULT.equals(query)) {
-                mSession.notifySearchResultChanged(controllerInfo, query, 0, extras);
-            } else {
-                // TODO: For the error case, how should we notify the browser?
-            }
-        }
-
-        @Override
-        public List<MediaItem2> onGetSearchResult(MediaLibrarySession session,
-                ControllerInfo controllerInfo, String query, int page, int pageSize,
-                Bundle extras) {
-            if (SEARCH_QUERY.equals(query)) {
-                return getPaginatedResult(SEARCH_RESULT, page, pageSize);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public void onSubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo controller, @NonNull String parentId,
-                @Nullable Bundle extras) {
-            mCallbackProxy.onSubscribe(session, controller, parentId, extras);
-        }
-
-        @Override
-        public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo controller, String parentId) {
-            mCallbackProxy.onUnsubscribe(session, controller, parentId);
-        }
-    }
-
-    private List<MediaItem2> getPaginatedResult(List<MediaItem2> items, int page, int pageSize) {
-        if (items == null) {
-            return null;
-        } else if (items.size() == 0) {
-            return new ArrayList<>();
-        }
-
-        final int totalItemCount = items.size();
-        int fromIndex = (page - 1) * pageSize;
-        int toIndex = Math.min(page * pageSize, totalItemCount);
-
-        List<MediaItem2> paginatedResult = new ArrayList<>();
-        try {
-            // The case of (fromIndex >= totalItemCount) will throw exception below.
-            paginatedResult = items.subList(fromIndex, toIndex);
-        } catch (IndexOutOfBoundsException | IllegalArgumentException ex) {
-            Log.d(TAG, "Result is empty for given pagination arguments: totalItemCount="
-                    + totalItemCount + ", page=" + page + ", pageSize=" + pageSize, ex);
-        }
-        return paginatedResult;
-    }
-
-    private MediaItem2 createMediaItem(String mediaId) {
-        Context context = MockMediaLibraryService2.this;
-        return new MediaItem2.Builder(context, 0 /* Flags */)
-                .setMediaId(mediaId)
-                .setDataSourceDesc(DATA_SOURCE_DESC)
-                .setMetadata(new MediaMetadata2.Builder(context)
-                                .putString(MediaMetadata2.METADATA_KEY_MEDIA_ID, mediaId)
-                                .build())
-                .build();
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java b/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java
deleted file mode 100644
index 64b1acd..0000000
--- a/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static junit.framework.Assert.fail;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.support.annotation.NonNull;
-
-import java.util.concurrent.Executor;
-
-/**
- * Mock implementation of {@link android.media.MediaSessionService2} for testing.
- */
-public class MockMediaSessionService2 extends MediaSessionService2 {
-    // Keep in sync with the AndroidManifest.xml
-    public static final String ID = "TestSession";
-
-    private static final String DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID = "media_session_service";
-    private static final int DEFAULT_MEDIA_NOTIFICATION_ID = 1001;
-
-    private NotificationChannel mDefaultNotificationChannel;
-    private MediaSession2 mSession;
-    private NotificationManager mNotificationManager;
-
-    @Override
-    public void onCreate() {
-        TestServiceRegistry.getInstance().setServiceInstance(this);
-        super.onCreate();
-        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-    }
-
-    @Override
-    public MediaSession2 onCreateSession(String sessionId) {
-        final MockPlayer player = new MockPlayer(1);
-        final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler();
-        final Executor executor = (runnable) -> handler.post(runnable);
-        SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance()
-                .getSessionCallbackProxy();
-        if (sessionCallbackProxy == null) {
-            // Ensures non-null
-            sessionCallbackProxy = new SessionCallbackProxy(this) {};
-        }
-        TestSessionServiceCallback callback =
-                new TestSessionServiceCallback(sessionCallbackProxy);
-        mSession = new MediaSession2.Builder(this)
-                .setPlayer(player)
-                .setSessionCallback(executor, callback)
-                .setId(sessionId).build();
-        return mSession;
-    }
-
-    @Override
-    public void onDestroy() {
-        TestServiceRegistry.getInstance().cleanUp();
-        super.onDestroy();
-    }
-
-    @Override
-    public MediaNotification onUpdateNotification() {
-        if (mDefaultNotificationChannel == null) {
-            mDefaultNotificationChannel = new NotificationChannel(
-                    DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID,
-                    DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID,
-                    NotificationManager.IMPORTANCE_DEFAULT);
-            mNotificationManager.createNotificationChannel(mDefaultNotificationChannel);
-        }
-        Notification notification = new Notification.Builder(
-                this, DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID)
-                .setContentTitle(getPackageName())
-                .setContentText("Dummt test notification")
-                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
-        return new MediaNotification(this, DEFAULT_MEDIA_NOTIFICATION_ID, notification);
-    }
-
-    private class TestSessionServiceCallback extends SessionCallback {
-        private final SessionCallbackProxy mCallbackProxy;
-
-        public TestSessionServiceCallback(SessionCallbackProxy callbackProxy) {
-            super(MockMediaSessionService2.this);
-            mCallbackProxy = callbackProxy;
-        }
-
-        @Override
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            return mCallbackProxy.onConnect(session, controller);
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockPlayer.java b/packages/MediaComponents/test/src/android/media/MockPlayer.java
deleted file mode 100644
index 05962cf..0000000
--- a/packages/MediaComponents/test/src/android/media/MockPlayer.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import android.media.MediaSession2.PlaylistParams;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.ArrayMap;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-
-/**
- * A mock implementation of {@link MediaPlayerBase} for testing.
- */
-public class MockPlayer extends MediaPlayerBase {
-    public final CountDownLatch mCountDownLatch;
-
-    public boolean mPlayCalled;
-    public boolean mPauseCalled;
-    public boolean mStopCalled;
-    public boolean mSkipToPreviousCalled;
-    public boolean mSkipToNextCalled;
-    public boolean mPrepareCalled;
-    public boolean mFastForwardCalled;
-    public boolean mRewindCalled;
-    public boolean mSeekToCalled;
-    public long mSeekPosition;
-    public boolean mSetCurrentPlaylistItemCalled;
-    public MediaItem2 mCurrentItem;
-    public boolean mSetPlaylistCalled;
-    public boolean mSetPlaylistParamsCalled;
-
-    public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
-    public List<MediaItem2> mPlaylist;
-    public PlaylistParams mPlaylistParams;
-
-    private PlaybackState2 mLastPlaybackState;
-    private AudioAttributes mAudioAttributes;
-
-    public MockPlayer(int count) {
-        mCountDownLatch = (count > 0) ? new CountDownLatch(count) : null;
-    }
-
-    @Override
-    public void close() {
-        // no-op
-    }
-
-    @Override
-    public void reset() {
-        // no-op
-    }
-
-    @Override
-    public void play() {
-        mPlayCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    @Override
-    public void pause() {
-        mPauseCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void stop() {
-        mStopCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void skipToPrevious() {
-        mSkipToPreviousCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    @Override
-    public void skipToNext() {
-        mSkipToNextCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    @Override
-    public void prepare() {
-        mPrepareCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void fastForward() {
-        mFastForwardCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void rewind() {
-        mRewindCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    @Override
-    public void seekTo(long pos) {
-        mSeekToCalled = true;
-        mSeekPosition = pos;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setCurrentPlaylistItem(MediaItem2 item) {
-        mSetCurrentPlaylistItemCalled = true;
-        mCurrentItem = item;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Nullable
-    @Override
-    public PlaybackState2 getPlaybackState() {
-        return mLastPlaybackState;
-    }
-    */
-
-    @Override
-    public int getPlayerState() {
-        return mLastPlaybackState.getState();
-    }
-
-    @Override
-    public int getBufferingState() {
-        // TODO: implement this
-        return -1;
-    }
-
-    @Override
-    public void registerPlayerEventCallback(@NonNull Executor executor,
-            @NonNull PlayerEventCallback callback) {
-        mCallbacks.put(callback, executor);
-    }
-
-    @Override
-    public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) {
-        mCallbacks.remove(callback);
-    }
-
-    public void notifyPlaybackState(final PlaybackState2 state) {
-        mLastPlaybackState = state;
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            final PlayerEventCallback callback = mCallbacks.keyAt(i);
-            final Executor executor = mCallbacks.valueAt(i);
-            // TODO: Uncomment or remove
-            //executor.execute(() -> callback.onPlaybackStateChanged(state));
-        }
-    }
-
-    public void notifyError(int what) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            final PlayerEventCallback callback = mCallbacks.keyAt(i);
-            final Executor executor = mCallbacks.valueAt(i);
-            // TODO: Uncomment or remove
-            //executor.execute(() -> callback.onError(null, what, 0));
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setPlaylistParams(PlaylistParams params) {
-        mSetPlaylistParamsCalled = true;
-        mPlaylistParams = params;
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void addPlaylistItem(int index, MediaItem2 item) {
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void removePlaylistItem(MediaItem2 item) {
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public PlaylistParams getPlaylistParams() {
-        return mPlaylistParams;
-    }
-    */
-
-    @Override
-    public void setAudioAttributes(AudioAttributes attributes) {
-        mAudioAttributes = attributes;
-    }
-
-    @Override
-    public AudioAttributes getAudioAttributes() {
-        return mAudioAttributes;
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setPlaylist(List<MediaItem2> playlist) {
-        mSetPlaylistCalled = true;
-        mPlaylist = playlist;
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public List<MediaItem2> getPlaylist() {
-        return mPlaylist;
-    }
-    */
-
-    @Override
-    public void setDataSource(@NonNull DataSourceDesc dsd) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public void setNextDataSource(@NonNull DataSourceDesc dsd) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public DataSourceDesc getCurrentDataSource() {
-        // TODO: Implement this
-        return null;
-    }
-
-    @Override
-    public void loopCurrent(boolean loop) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setPlaybackSpeed(float speed) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setPlayerVolume(float volume) {
-        // TODO: implement this
-    }
-
-    @Override
-    public float getPlayerVolume() {
-        // TODO: implement this
-        return -1;
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/SessionToken2Test.java b/packages/MediaComponents/test/src/android/media/SessionToken2Test.java
deleted file mode 100644
index efde78a..0000000
--- a/packages/MediaComponents/test/src/android/media/SessionToken2Test.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.content.Context;
-import android.os.Process;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests {@link SessionToken2}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SessionToken2Test {
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    public void testConstructor_sessionService() {
-        SessionToken2 token = new SessionToken2(mContext, mContext.getPackageName(),
-                MockMediaSessionService2.class.getCanonicalName());
-        assertEquals(MockMediaSessionService2.ID, token.getId());
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(Process.myUid(), token.getUid());
-        assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-    }
-
-    @Test
-    public void testConstructor_libraryService() {
-        SessionToken2 token = new SessionToken2(mContext, mContext.getPackageName(),
-                MockMediaLibraryService2.class.getCanonicalName());
-        assertEquals(MockMediaLibraryService2.ID, token.getId());
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(Process.myUid(), token.getUid());
-        assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-    }
-}
\ No newline at end of file
diff --git a/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java b/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java
deleted file mode 100644
index 27b6f89..0000000
--- a/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.TestUtils.SyncHandler;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Process;
-import android.support.annotation.GuardedBy;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-/**
- * Keeps the instance of currently running {@link MockMediaSessionService2}. And also provides
- * a way to control them in one place.
- * <p>
- * It only support only one service at a time.
- */
-public class TestServiceRegistry {
-    /**
-     * Proxy for both {@link MediaSession2.SessionCallback} and
-     * {@link MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback}.
-     */
-    public static abstract class SessionCallbackProxy {
-        private final Context mContext;
-
-        /**
-         * Constructor
-         */
-        public SessionCallbackProxy(Context context) {
-            mContext = context;
-        }
-
-        public final Context getContext() {
-            return mContext;
-        }
-
-        /**
-         * @param controller
-         * @return
-         */
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            if (Process.myUid() == controller.getUid()) {
-                CommandGroup commands = new CommandGroup(mContext);
-                commands.addAllPredefinedCommands();
-                return commands;
-            }
-            return null;
-        }
-
-        /**
-         * Called when enclosing service is created.
-         */
-        public void onServiceCreated(MediaSessionService2 service) { }
-
-        /**
-         * Called when enclosing service is destroyed.
-         */
-        public void onServiceDestroyed() { }
-
-        public void onSubscribe(@NonNull MediaLibrarySession session, @NonNull ControllerInfo info,
-                @NonNull String parentId, @Nullable Bundle extra) { }
-        public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo info, @NonNull String parentId) { }
-    }
-
-    @GuardedBy("TestServiceRegistry.class")
-    private static TestServiceRegistry sInstance;
-    @GuardedBy("TestServiceRegistry.class")
-    private MediaSessionService2 mService;
-    @GuardedBy("TestServiceRegistry.class")
-    private SyncHandler mHandler;
-    @GuardedBy("TestServiceRegistry.class")
-    private SessionCallbackProxy mCallbackProxy;
-
-    public static TestServiceRegistry getInstance() {
-        synchronized (TestServiceRegistry.class) {
-            if (sInstance == null) {
-                sInstance = new TestServiceRegistry();
-            }
-            return sInstance;
-        }
-    }
-
-    public void setHandler(Handler handler) {
-        synchronized (TestServiceRegistry.class) {
-            mHandler = new SyncHandler(handler.getLooper());
-        }
-    }
-
-    public Handler getHandler() {
-        synchronized (TestServiceRegistry.class) {
-            return mHandler;
-        }
-    }
-
-    public void setSessionCallbackProxy(SessionCallbackProxy callbackProxy) {
-        synchronized (TestServiceRegistry.class) {
-            mCallbackProxy = callbackProxy;
-        }
-    }
-
-    public SessionCallbackProxy getSessionCallbackProxy() {
-        synchronized (TestServiceRegistry.class) {
-            return mCallbackProxy;
-        }
-    }
-
-    public void setServiceInstance(MediaSessionService2 service) {
-        synchronized (TestServiceRegistry.class) {
-            if (mService != null) {
-                fail("Previous service instance is still running. Clean up manually to ensure"
-                        + " previoulsy running service doesn't break current test");
-            }
-            mService = service;
-            if (mCallbackProxy != null) {
-                mCallbackProxy.onServiceCreated(service);
-            }
-        }
-    }
-
-    public MediaSessionService2 getServiceInstance() {
-        synchronized (TestServiceRegistry.class) {
-            return mService;
-        }
-    }
-
-    public void cleanUp() {
-        synchronized (TestServiceRegistry.class) {
-            final SessionCallbackProxy callbackProxy = mCallbackProxy;
-            if (mService != null) {
-                mService.getSession().close();
-                // stopSelf() would not kill service while the binder connection established by
-                // bindService() exists, and close() above will do the job instead.
-                // So stopSelf() isn't really needed, but just for sure.
-                mService.stopSelf();
-                mService = null;
-            }
-            if (mHandler != null) {
-                mHandler.removeCallbacksAndMessages(null);
-            }
-            mCallbackProxy = null;
-
-            if (callbackProxy != null) {
-                callbackProxy.onServiceDestroyed();
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/TestUtils.java b/packages/MediaComponents/test/src/android/media/TestUtils.java
deleted file mode 100644
index 12b24c0..0000000
--- a/packages/MediaComponents/test/src/android/media/TestUtils.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2018 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;
-
-import android.content.Context;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.session.MediaSessionManager;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.os.Handler;
-
-import android.os.Looper;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * Utilities for tests.
- */
-public final class TestUtils {
-    private static final int WAIT_TIME_MS = 1000;
-    private static final int WAIT_SERVICE_TIME_MS = 5000;
-
-    /**
-     * Finds the session with id in this test package.
-     *
-     * @param context
-     * @param id
-     * @return
-     */
-    // TODO(jaewan): Currently not working.
-    public static SessionToken2 getServiceToken(Context context, String id) {
-        MediaSessionManager manager =
-                (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        List<SessionToken2> tokens = manager.getSessionServiceTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (context.getPackageName().equals(token.getPackageName())
-                    && id.equals(token.getId())) {
-                return token;
-            }
-        }
-        fail("Failed to find service");
-        return null;
-    }
-
-    /**
-     * Compares contents of two bundles.
-     *
-     * @param a a bundle
-     * @param b another bundle
-     * @return {@code true} if two bundles are the same. {@code false} otherwise. This may be
-     *     incorrect if any bundle contains a bundle.
-     */
-    public static boolean equals(Bundle a, Bundle b) {
-        if (a == b) {
-            return true;
-        }
-        if (a == null || b == null) {
-            return false;
-        }
-        if (!a.keySet().containsAll(b.keySet())
-                || !b.keySet().containsAll(a.keySet())) {
-            return false;
-        }
-        for (String key : a.keySet()) {
-            if (!Objects.equals(a.get(key), b.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public static void ensurePlaylistParamsModeEquals(PlaylistParams a, PlaylistParams b) {
-        assertEquals(a.getRepeatMode(), b.getRepeatMode());
-        assertEquals(a.getShuffleMode(), b.getShuffleMode());
-    }
-
-    /**
-     * Handler that always waits until the Runnable finishes.
-     */
-    public static class SyncHandler extends Handler {
-        public SyncHandler(Looper looper) {
-            super(looper);
-        }
-
-        public void postAndSync(Runnable runnable) throws InterruptedException {
-            final CountDownLatch latch = new CountDownLatch(1);
-            if (getLooper() == Looper.myLooper()) {
-                runnable.run();
-            } else {
-                post(()->{
-                    runnable.run();
-                    latch.countDown();
-                });
-                assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-    }
-}
