Merge "CTS: Update TextClassificationManagerTests" into oc-dev
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index acd346a..476eb80 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -29,6 +29,7 @@
 import android.media.audiofx.AudioEffect;
 import android.net.Uri;
 import android.nfc.cardemulation.CardEmulation;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.UserHandle;
@@ -67,7 +68,6 @@
                 new Intent(AlarmClock.ACTION_SET_TIMER),
                 new Intent(AlarmClock.ACTION_SHOW_ALARMS),
                 new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS),
-                new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS),
                 new Intent(Settings.ACTION_CAPTIONING_SETTINGS),
                 new Intent(Settings.ACTION_DATE_SETTINGS),
                 new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS),
@@ -266,6 +266,11 @@
             notForwardedIntentsFromManaged.add(
                     new Intent(Settings.ACTION_PRINT_SETTINGS));
         }
+
+        if (Build.TYPE.equals("user")) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS));
+        }
     }
 
     public boolean checkCrossProfileIntentFilters(int flag) {
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
index 22eaaea..9778f12 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
@@ -41,6 +41,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.UUID;
 
 /**
  * Client app for verifying storage behaviors.
@@ -85,8 +86,10 @@
     public void testVerifySpaceApi() throws Exception {
         final StorageManager sm = getContext().getSystemService(StorageManager.class);
 
-        final long cacheSize = sm.getCacheSizeBytes(getContext().getCacheDir());
-        final long extCacheSize = sm.getCacheSizeBytes(getContext().getExternalCacheDir());
+        final long cacheSize = sm.getCacheSizeBytes(
+                sm.getUuidForPath(getContext().getCacheDir()));
+        final long extCacheSize = sm.getCacheSizeBytes(
+                sm.getUuidForPath(getContext().getExternalCacheDir()));
         if (cacheSize == extCacheSize) {
             assertMostlyEquals(CACHE_ALL, cacheSize);
         } else {
@@ -97,22 +100,28 @@
 
     public void testVerifyQuotaApi() throws Exception {
         final StorageManager sm = getContext().getSystemService(StorageManager.class);
-        assertTrue("Apps must have at least 10MB quota",
-                sm.getCacheQuotaBytes(getContext().getCacheDir()) > 10 * MB_IN_BYTES);
+
+        final long cacheSize = sm.getCacheQuotaBytes(
+                sm.getUuidForPath(getContext().getCacheDir()));
+        assertTrue("Apps must have at least 10MB quota", cacheSize > 10 * MB_IN_BYTES);
     }
 
     public void testVerifyAllocateApi() throws Exception {
         final StorageManager sm = getContext().getSystemService(StorageManager.class);
 
         final File filesDir = getContext().getFilesDir();
-        assertTrue("Apps must be able to allocate internal space",
-                sm.getAllocatableBytes(filesDir, 0) > 10 * MB_IN_BYTES);
         final File extDir = Environment.getExternalStorageDirectory();
+
+        final UUID filesUuid = sm.getUuidForPath(filesDir);
+        final UUID extUuid = sm.getUuidForPath(extDir);
+
+        assertTrue("Apps must be able to allocate internal space",
+                sm.getAllocatableBytes(filesUuid, 0) > 10 * MB_IN_BYTES);
         assertTrue("Apps must be able to allocate external space",
-                sm.getAllocatableBytes(extDir, 0) > 10 * MB_IN_BYTES);
+                sm.getAllocatableBytes(extUuid, 0) > 10 * MB_IN_BYTES);
 
         // Should always be able to allocate 1MB indirectly
-        sm.allocateBytes(filesDir, 1 * MB_IN_BYTES, 0);
+        sm.allocateBytes(filesUuid, 1 * MB_IN_BYTES, 0);
 
         // Should always be able to allocate 1MB directly
         final File filesFile = makeUniqueFile(filesDir);
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/UtilsReceiver.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/UtilsReceiver.java
index bab84aa..2845185 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/UtilsReceiver.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/UtilsReceiver.java
@@ -50,13 +50,13 @@
     public static Bundle doAllocation(Context context, Bundle extras) {
         final StorageManager sm = context.getSystemService(StorageManager.class);
 
-        final double fraction = extras.getDouble(EXTRA_FRACTION, 0);
-        final long quota = sm.getCacheQuotaBytes(context.getCacheDir());
-        final long bytes = (long) (quota * fraction);
-        final long time = extras.getLong(EXTRA_TIME, System.currentTimeMillis());
-
         long allocated = 0;
         try {
+            final double fraction = extras.getDouble(EXTRA_FRACTION, 0);
+            final long quota = sm.getCacheQuotaBytes(sm.getUuidForPath(context.getCacheDir()));
+            final long bytes = (long) (quota * fraction);
+            final long time = extras.getLong(EXTRA_TIME, System.currentTimeMillis());
+
             while (allocated < bytes) {
                 final File f = makeUniqueFile(context.getCacheDir());
                 final long size = 1024 * 1024;
@@ -64,15 +64,15 @@
                 f.setLastModified(time);
                 allocated += Os.stat(f.getAbsolutePath()).st_blocks * 512;
             }
+
+            Log.d(TAG, "Quota " + quota + ", target " + bytes + ", allocated " + allocated);
+
+            final Bundle res = new Bundle();
+            res.putLong(EXTRA_BYTES, allocated);
+            return res;
         } catch (Exception e) {
             Log.e(TAG, "Failed to allocate cache files", e);
             return null;
         }
-
-        Log.d(TAG, "Quota " + quota + ", target " + bytes + ", allocated " + allocated);
-
-        final Bundle res = new Bundle();
-        res.putLong(EXTRA_BYTES, allocated);
-        return res;
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
index 72a420d..41439f0 100644
--- a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.storagestatsapp;
 
+import static android.os.storage.StorageManager.UUID_DEFAULT;
+
 import static com.android.cts.storageapp.Utils.CACHE_ALL;
 import static com.android.cts.storageapp.Utils.DATA_ALL;
 import static com.android.cts.storageapp.Utils.MB_IN_BYTES;
@@ -54,6 +56,7 @@
 import com.android.cts.storageapp.UtilsReceiver;
 
 import java.io.File;
+import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -81,15 +84,18 @@
                     .getSystemService(StorageStatsManager.class);
             assertTrue("You're running kernel 3.18 or newer (" + uname.release + ") which "
                     + "means that CONFIG_QUOTA, CONFIG_QFMT_V2, CONFIG_QUOTACTL and the "
-                    + "'quota' fstab option on /data are required", stats.isQuotaSupported(null));
+                    + "'quota' fstab option on /data are required",
+                    stats.isQuotaSupported(UUID_DEFAULT));
         }
     }
 
     public void testVerifySummary() throws Exception {
         final StorageStatsManager stats = getContext().getSystemService(StorageStatsManager.class);
 
-        assertAtLeast(Environment.getDataDirectory().getTotalSpace(), stats.getTotalBytes(null));
-        assertAtLeast(Environment.getDataDirectory().getUsableSpace(), stats.getFreeBytes(null));
+        assertAtLeast(Environment.getDataDirectory().getTotalSpace(),
+                stats.getTotalBytes(UUID_DEFAULT));
+        assertAtLeast(Environment.getDataDirectory().getUsableSpace(),
+                stats.getFreeBytes(UUID_DEFAULT));
     }
 
     public void testVerifyStats() throws Exception {
@@ -97,13 +103,13 @@
         final int uid = android.os.Process.myUid();
         final UserHandle user = UserHandle.getUserHandleForUid(uid);
 
-        final StorageStats beforeApp = stats.queryStatsForUid(null, uid);
-        final StorageStats beforeUser = stats.queryStatsForUser(null, user);
+        final StorageStats beforeApp = stats.queryStatsForUid(UUID_DEFAULT, uid);
+        final StorageStats beforeUser = stats.queryStatsForUser(UUID_DEFAULT, user);
 
         useSpace(getContext());
 
-        final StorageStats afterApp = stats.queryStatsForUid(null, uid);
-        final StorageStats afterUser = stats.queryStatsForUser(null, user);
+        final StorageStats afterApp = stats.queryStatsForUid(UUID_DEFAULT, uid);
+        final StorageStats afterUser = stats.queryStatsForUser(UUID_DEFAULT, user);
 
         final long deltaData = DATA_ALL;
         assertMostlyEquals(deltaData, afterApp.getDataBytes() - beforeApp.getDataBytes());
@@ -121,8 +127,8 @@
         final ApplicationInfo a = pm.getApplicationInfo(PKG_A, 0);
         final ApplicationInfo b = pm.getApplicationInfo(PKG_B, 0);
 
-        final StorageStats as = stats.queryStatsForUid(null, a.uid);
-        final StorageStats bs = stats.queryStatsForUid(null, b.uid);
+        final StorageStats as = stats.queryStatsForUid(UUID_DEFAULT, a.uid);
+        final StorageStats bs = stats.queryStatsForUid(UUID_DEFAULT, b.uid);
 
         assertMostlyEquals(DATA_ALL * 2, as.getDataBytes());
         assertMostlyEquals(CACHE_ALL * 2, as.getCacheBytes());
@@ -140,7 +146,7 @@
         final int uid = android.os.Process.myUid();
         final UserHandle user = UserHandle.getUserHandleForUid(uid);
 
-        final ExternalStorageStats before = stats.queryExternalStatsForUser(null, user);
+        final ExternalStorageStats before = stats.queryExternalStatsForUser(UUID_DEFAULT, user);
 
         final File dir = Environment.getExternalStorageDirectory();
         final File downloadsDir = Environment.getExternalStoragePublicDirectory(
@@ -158,7 +164,7 @@
         useWrite(audio, 5 * MB_IN_BYTES);
         useWrite(internal, 7 * MB_IN_BYTES);
 
-        final ExternalStorageStats afterInit = stats.queryExternalStatsForUser(null, user);
+        final ExternalStorageStats afterInit = stats.queryExternalStatsForUser(UUID_DEFAULT, user);
 
         assertMostlyEquals(17 * MB_IN_BYTES, afterInit.getTotalBytes() - before.getTotalBytes());
         assertMostlyEquals(5 * MB_IN_BYTES, afterInit.getAudioBytes() - before.getAudioBytes());
@@ -168,7 +174,7 @@
         // Rename to ensure that stats are updated
         video.renameTo(new File(dir, System.nanoTime() + ".PnG"));
 
-        final ExternalStorageStats afterRename = stats.queryExternalStatsForUser(null, user);
+        final ExternalStorageStats afterRename = stats.queryExternalStatsForUser(UUID_DEFAULT, user);
 
         assertMostlyEquals(17 * MB_IN_BYTES, afterRename.getTotalBytes() - before.getTotalBytes());
         assertMostlyEquals(5 * MB_IN_BYTES, afterRename.getAudioBytes() - before.getAudioBytes());
@@ -199,7 +205,7 @@
         logCommand("sync");
 
         final long manualSize = getSizeManual(Environment.getExternalStorageDirectory());
-        final long statsSize = stats.queryExternalStatsForUser(null, user).getTotalBytes();
+        final long statsSize = stats.queryExternalStatsForUser(UUID_DEFAULT, user).getTotalBytes();
 
         assertMostlyEquals(manualSize, statsSize);
     }
@@ -220,9 +226,10 @@
         final UserHandle user = android.os.Process.myUserHandle();
 
         final File filesDir = context.getFilesDir();
+        final UUID filesUuid = sm.getUuidForPath(filesDir);
 
-        final long beforeAllocatable = sm.getAllocatableBytes(filesDir, 0);
-        final long beforeFree = stats.getFreeBytes(null);
+        final long beforeAllocatable = sm.getAllocatableBytes(filesUuid, 0);
+        final long beforeFree = stats.getFreeBytes(UUID_DEFAULT);
         final long beforeRaw = filesDir.getUsableSpace();
 
         Log.d(TAG, "Before raw " + beforeRaw + ", free " + beforeFree + ", allocatable "
@@ -239,16 +246,16 @@
         // Apps using up some cache space shouldn't change how much we can
         // allocate, or how much we think is free; but it should decrease real
         // disk space.
-        if (stats.isQuotaSupported(null)) {
+        if (stats.isQuotaSupported(UUID_DEFAULT)) {
             assertMostlyEquals(beforeAllocatable,
-                    sm.getAllocatableBytes(filesDir, 0), 10 * MB_IN_BYTES);
+                    sm.getAllocatableBytes(filesUuid, 0), 10 * MB_IN_BYTES);
             assertMostlyEquals(beforeFree,
-                    stats.getFreeBytes(null), 10 * MB_IN_BYTES);
+                    stats.getFreeBytes(UUID_DEFAULT), 10 * MB_IN_BYTES);
         } else {
             assertMostlyEquals(beforeAllocatable - totalAllocated,
-                    sm.getAllocatableBytes(filesDir, 0), 10 * MB_IN_BYTES);
+                    sm.getAllocatableBytes(filesUuid, 0), 10 * MB_IN_BYTES);
             assertMostlyEquals(beforeFree - totalAllocated,
-                    stats.getFreeBytes(null), 10 * MB_IN_BYTES);
+                    stats.getFreeBytes(UUID_DEFAULT), 10 * MB_IN_BYTES);
         }
         assertMostlyEquals(beforeRaw - totalAllocated,
                 filesDir.getUsableSpace(), 10 * MB_IN_BYTES);
@@ -259,7 +266,7 @@
         // Allocate some space for ourselves, which should trim away at
         // over-quota app first, even though its files are newer.
         final long clear1 = filesDir.getUsableSpace() + (targetB / 2);
-        sm.allocateBytes(filesDir, clear1, 0);
+        sm.allocateBytes(filesUuid, clear1, 0);
 
         assertMostlyEquals(targetA, getCacheBytes(PKG_A, user));
         assertMostlyEquals(targetB / 2, getCacheBytes(PKG_B, user), 2 * MB_IN_BYTES);
@@ -269,7 +276,7 @@
         // they're tied for cache ratios, we expect to clear about half of the
         // remaining space from each of them.
         final long clear2 = filesDir.getUsableSpace() + (targetB / 2);
-        sm.allocateBytes(filesDir, clear2, 0);
+        sm.allocateBytes(filesUuid, clear2, 0);
 
         assertMostlyEquals(targetA / 2, getCacheBytes(PKG_A, user), 2 * MB_IN_BYTES);
         assertMostlyEquals(targetA / 2, getCacheBytes(PKG_B, user), 2 * MB_IN_BYTES);
@@ -313,7 +320,7 @@
         tomb.setLastModified(tombTime);
 
         final long clear1 = group.getUsableSpace() + (8 * MB_IN_BYTES);
-        sm.allocateBytes(group, clear1, 0);
+        sm.allocateBytes(sm.getUuidForPath(group), clear1, 0);
 
         assertTrue(a.exists());
         assertTrue(b.exists());
@@ -327,9 +334,9 @@
         assertTrue(i.exists()); assertEquals(0, i.length());
     }
 
-    private long getCacheBytes(String pkg, UserHandle user) {
+    private long getCacheBytes(String pkg, UserHandle user) throws Exception {
         return getContext().getSystemService(StorageStatsManager.class)
-                .queryStatsForPackage(null, pkg, user).getCacheBytes();
+                .queryStatsForPackage(UUID_DEFAULT, pkg, user).getCacheBytes();
     }
 
     private long doAllocateReceiver(String pkg, double fraction, long time) throws Exception {
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java
index 7528cac..4570cdf 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsBgVsFgActions.java
@@ -16,11 +16,14 @@
 
 package com.android.server.cts.device.batterystats;
 
+import android.accounts.Account;
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.app.job.JobInfo;
 import android.app.job.JobScheduler;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -31,6 +34,7 @@
 import android.os.Looper;
 import android.util.Log;
 
+
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -40,6 +44,7 @@
 
     public static final String KEY_ACTION = "action";
     public static final String ACTION_JOB_SCHEDULE = "action.jobs";
+    public static final String ACTION_SYNC = "action.sync";
     public static final String ACTION_WIFI_SCAN = "action.wifi_scan";
 
     /** Perform the action specified by the given action code (see constants above). */
@@ -53,6 +58,9 @@
             case ACTION_JOB_SCHEDULE:
                 doScheduleJob(ctx);
                 break;
+            case ACTION_SYNC:
+                doSync(ctx);
+                break;
             case ACTION_WIFI_SCAN:
                 doWifi(ctx);
                 break;
@@ -86,6 +94,41 @@
         }.execute();
     }
 
+    private static void doSync(Context ctx) {
+        BatteryStatsAuthenticator.removeAllAccounts(ctx);
+        final Account account = BatteryStatsAuthenticator.getTestAccount();
+        // Create the test account.
+        BatteryStatsAuthenticator.ensureTestAccount(ctx);
+        // Force set is syncable.
+        ContentResolver.setMasterSyncAutomatically(true);
+        ContentResolver.setIsSyncable(account, BatteryStatsProvider.AUTHORITY, 1);
+
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                try {
+                    Log.v(TAG, "Starting sync");
+                    BatteryStatsSyncAdapter.requestSync(account);
+                    sleep(500);
+                } catch (Exception e) {
+                    Log.e(TAG, "Exception trying to sync", e);
+                }
+                BatteryStatsAuthenticator.removeAllAccounts(ctx);
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(Void aVoid) {
+                super.onPostExecute(aVoid);
+                Log.v(TAG, "Finished sync method");
+                // If ctx is an Activity, finish it when sync is done. If it's a service, don't.
+                if(ctx instanceof Activity){
+                    ((Activity) ctx).finish();
+                }
+            }
+        }.execute();
+    }
+
     private static void doWifi(Context ctx) {
         IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
         CountDownLatch onReceiveLatch = new CountDownLatch(1);
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsForegroundActivity.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsForegroundActivity.java
index d6869a1..c41b244 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsForegroundActivity.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsForegroundActivity.java
@@ -18,6 +18,7 @@
 
 import static com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions
         .ACTION_JOB_SCHEDULE;
+import static com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions.ACTION_SYNC;
 import static com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions.KEY_ACTION;
 import static com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions.doAction;
 import static com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions.isAppInBackground;
@@ -51,7 +52,12 @@
             Log.w(TAG, "Couldn't determine if app is in foreground. Proceeding with test anyway");
         }
 
-        doAction(this, intent.getStringExtra(KEY_ACTION));
-        finish();
+        String action = intent.getStringExtra(KEY_ACTION);
+        doAction(this, action);
+
+        // ACTION_SYNC will finish itself. Others get finished here.
+        if (!ACTION_SYNC.equals(action)) {
+            finish();
+        }
     }
 }
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
index c619166..c40c950 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsProcessStateTests.java
@@ -34,12 +34,7 @@
     public void testForegroundService() throws Exception {
         Intent intent = new Intent();
         intent.setClass(mContext, SimpleForegroundService.class);
-        Notification notification = new Notification.Builder(mContext, "Foreground Service")
-                .setContentTitle("CTS Foreground")
-                .setSmallIcon(android.R.drawable.ic_secure)
-                .build();
-        mContext.getSystemService(NotificationManager.class).startServiceInForeground(intent,
-                1, notification);
+        mContext.startForegroundService(intent);
         Thread.sleep(3000);
     }
 
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsWifiTransferTests.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsWifiTransferTests.java
index 394a070..de0954d 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsWifiTransferTests.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsWifiTransferTests.java
@@ -63,6 +63,9 @@
     /** String extra of any error encountered during wifi transfer. */
     private static final String EXTRA_TRANSFER_ERROR = "transfer_error";
 
+    /** String extra: the service is required to startForeground() */
+    private static final String EXTRA_FOREGROUND = "fg";
+
     private static final int READ_BUFFER_SIZE = 4096;
 
     /** Server to send requests to. */
@@ -120,15 +123,10 @@
         if (!mHasFeature) {
             return;
         }
-        mTransferService.putExtra(EXTRA_ACTION, action);
-        Notification notification =
-            new Notification.Builder(mContext, "Wifi Transfer Foreground Service")
-                    .setContentTitle("Wifi Transfer Foreground")
-                    .setContentText("Wifi Transfer Foreground")
-                    .setSmallIcon(android.R.drawable.ic_secure)
-                    .build();
-        mContext.getSystemService(NotificationManager.class).startServiceInForeground(mTransferService,
-                1, notification);
+        Intent launchIntent = new Intent(mTransferService)
+                .putExtra(EXTRA_ACTION, action)
+                .putExtra(EXTRA_FOREGROUND, true);
+        mContext.startForegroundService(launchIntent);
 
         mResultsReceivedSignal.await(10, TimeUnit.SECONDS);
         assertTrue("Got error: " + mError, mError == null);
@@ -155,6 +153,16 @@
 
         @Override
         protected void onHandleIntent(Intent intent) {
+            if (intent.getBooleanExtra(EXTRA_FOREGROUND, false)) {
+                Notification notification =
+                        new Notification.Builder(this, "Wifi Transfer Foreground Service")
+                                .setContentTitle("Wifi Transfer Foreground")
+                                .setContentText("Wifi Transfer Foreground")
+                                .setSmallIcon(android.R.drawable.ic_secure)
+                                .build();
+                startForeground(1, notification);
+            }
+
             String error = null;
             switch (intent.getStringExtra(EXTRA_ACTION)) {
                 case ACTION_DOWNLOAD:
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleForegroundService.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleForegroundService.java
index b8d4507..ed21615 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleForegroundService.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleForegroundService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.cts.device.batterystats;
 
+import android.app.Notification;
 import android.app.Service;
 import android.content.Intent;
 import android.os.Handler;
@@ -67,6 +68,12 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
+        Notification notification = new Notification.Builder(this, "Foreground Service")
+                .setContentTitle("CTS Foreground")
+                .setSmallIcon(android.R.drawable.ic_secure)
+                .build();
+        startForeground(1, notification);
+
         Message msg = mServiceHandler.obtainMessage();
         msg.arg1 = startId;
         mServiceHandler.sendMessage(msg);
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
index f6e9e31..3a96ccb 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
@@ -42,6 +42,7 @@
     // Constants from BatteryStatsBgVsFgActions.java (not directly accessible here).
     public static final String KEY_ACTION = "action";
     public static final String ACTION_JOB_SCHEDULE = "action.jobs";
+    public static final String ACTION_SYNC = "action.sync";
     public static final String ACTION_WIFI_SCAN = "action.wifi_scan";
 
     @Override
@@ -136,6 +137,26 @@
         batteryOffScreenOn();
     }
 
+    public void testSyncBgVsFg() throws Exception {
+        batteryOnScreenOff();
+        installPackage(DEVICE_SIDE_TEST_APK, true);
+
+        // Foreground test.
+        executeForeground(ACTION_SYNC);
+        Thread.sleep(3_000);
+        // Allow one or two syncs in this time frame (not just one) due to unpredictable syncs.
+        assertValueRange("sy", DEVICE_SIDE_SYNC_COMPONENT, 6, 1, 2); // count
+        assertValueRange("sy", DEVICE_SIDE_SYNC_COMPONENT, 8, 0, 0); // background_count
+
+        // Background test.
+        executeBackground(ACTION_SYNC);
+        Thread.sleep(3_000);
+        assertValueRange("sy", DEVICE_SIDE_SYNC_COMPONENT, 6, 2, 4); // count
+        assertValueRange("sy", DEVICE_SIDE_SYNC_COMPONENT, 8, 1, 2); // background_count
+
+        batteryOffScreenOn();
+    }
+
     public void testWifiScans() throws Exception {
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index 2fc0bc2..0f2965c 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -143,6 +143,8 @@
         assertBackgroundNetworkAccess(true);
         setBatterySaverMode(true);
         assertBackgroundNetworkAccess(false);
+        // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
+        setBatterySaverMode(false);
         turnBatteryOn();
         assertBackgroundNetworkAccess(true);
 
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 60d5cb9..b6857ae 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -100,6 +100,7 @@
     protected ConnectivityManager mCm;
     protected WifiManager mWfm;
     protected int mUid;
+    private int mMyUid;
     private String mMeteredWifi;
     private MyServiceClient mServiceClient;
     private boolean mHasWatch;
@@ -115,7 +116,7 @@
         mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mUid = getUid(TEST_APP2_PKG);
-        final int myUid = getUid(mContext.getPackageName());
+        mMyUid = getUid(mContext.getPackageName());
         mServiceClient = new MyServiceClient(mContext);
         mServiceClient.bind();
         mHasWatch = mContext.getPackageManager().hasSystemFeature(
@@ -128,7 +129,7 @@
         mSupported = setUpActiveNetworkMeteringState();
 
         Log.i(TAG, "Apps status on " + getName() + ":\n"
-                + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n"
+                + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
                 + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid));
    }
 
@@ -204,6 +205,21 @@
         assertEquals("wrong status", toString(expectedStatus), actualStatus);
     }
 
+    protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception {
+        final int actualStatus = mCm.getRestrictBackgroundStatus();
+        assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus));
+    }
+
+    protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception {
+        final int actualStatus = mCm.getRestrictBackgroundStatus();
+        if (expectedStatus != actualStatus) {
+            Log.d(TAG, "Expected: " + toString(expectedStatus)
+                    + " but actual: " + toString(actualStatus));
+            return false;
+        }
+        return true;
+    }
+
     protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
         assertBackgroundState(); // Sanity check.
         assertNetworkAccess(expectAllowed);
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index c3537c8..599a31c 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -20,16 +20,21 @@
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
 
+import android.util.Log;
+
 public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
 
     private static final String[] REQUIRED_WHITELISTED_PACKAGES = {
         "com.android.providers.downloads"
     };
 
+    private boolean mIsDataSaverSupported;
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
 
+        mIsDataSaverSupported = isDataSaverSupported();
         if (!isSupported()) return;
 
         // Set initial state.
@@ -59,6 +64,32 @@
         return setMeteredNetwork();
     }
 
+    @Override
+    protected boolean isSupported() throws Exception {
+        if (!mIsDataSaverSupported) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Data Saver Mode");
+        }
+        return mIsDataSaverSupported && super.isSupported();
+    }
+
+    /**
+     * As per CDD requirements, if the device doesn't support data saver mode then
+     * ConnectivityManager.getRestrictBackgroundStatus() will always return
+     * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if
+     * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns
+     * RESTRICT_BACKGROUND_STATUS_DISABLED or not.
+     */
+    private boolean isDataSaverSupported() throws Exception {
+        assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
+        try {
+            setRestrictBackground(true);
+            return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
+        } finally {
+            setRestrictBackground(false);
+        }
+    }
+
     public void testGetRestrictBackgroundStatus_disabled() throws Exception {
         if (!isSupported()) return;
 
diff --git a/hostsidetests/services/activityandwindowmanager/windowmanager/src/android/server/cts/CrossAppDragAndDropTests.java b/hostsidetests/services/activityandwindowmanager/windowmanager/src/android/server/cts/CrossAppDragAndDropTests.java
index f594123..6281e16 100644
--- a/hostsidetests/services/activityandwindowmanager/windowmanager/src/android/server/cts/CrossAppDragAndDropTests.java
+++ b/hostsidetests/services/activityandwindowmanager/windowmanager/src/android/server/cts/CrossAppDragAndDropTests.java
@@ -24,6 +24,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 public class CrossAppDragAndDropTests extends DeviceTestCase {
     // Constants copied from ActivityManager.StackId. If they are changed there, these must be
@@ -42,12 +43,18 @@
 
     private static final String AM_FORCE_STOP = "am force-stop ";
     private static final String AM_MOVE_TASK = "am stack move-task ";
+    private static final String AM_RESIZE_TASK = "am task resize ";
     private static final String AM_REMOVE_STACK = "am stack remove ";
     private static final String AM_START_N = "am start -n ";
     private static final String AM_STACK_LIST = "am stack list";
     private static final String INPUT_MOUSE_SWIPE = "input mouse swipe ";
     private static final String TASK_ID_PREFIX = "taskId";
 
+    // Regex pattern to match adb shell am stack list output of the form:
+    // taskId=<TASK_ID>: <componentName> bounds=[LEFT,TOP][RIGHT,BOTTOM]
+    private static final String TASK_REGEX_PATTERN_STRING =
+            "taskId=[0-9]+: %s bounds=\\[[0-9]+,[0-9]+\\]\\[[0-9]+,[0-9]+\\]";
+
     private static final int SWIPE_DURATION_MS = 500;
 
     private static final String SOURCE_PACKAGE_NAME = "android.wm.cts.dndsourceapp";
@@ -94,6 +101,9 @@
     private static final String RESULT_EXCEPTION = "Exception";
     private static final String RESULT_NULL_DROP_PERMISSIONS = "Null DragAndDropPermissions";
 
+    private static final String AM_SUPPORTS_SPLIT_SCREEN_MULTIWINDOW =
+            "am supports-split-screen-multiwindow";
+
     private ITestDevice mDevice;
 
     private Map<String, String> mSourceResults;
@@ -145,6 +155,12 @@
         return AM_MOVE_TASK + taskId + " " + stackId + " true";
     }
 
+    private String getResizeTaskCommand(int taskId, Point topLeft, Point bottomRight)
+            throws Exception {
+        return AM_RESIZE_TASK + taskId + " " + topLeft.x + " " + topLeft.y + " " + bottomRight.x
+                + " " + bottomRight.y;
+    }
+
     private String getComponentName(String packageName, String activityName) {
         return packageName + "/" + packageName + "." + activityName;
     }
@@ -195,6 +211,24 @@
         waitForResume(packageName, activityName);
     }
 
+    /**
+     * @param displaySize size of the display
+     * @param leftSide {@code true} to launch the app taking up the left half of the display,
+     *         {@code false} to launch the app taking up the right half of the display.
+     */
+    private void launchFreeformActivity(String packageName, String activityName, String mode,
+            Point displaySize, boolean leftSide) throws Exception{
+        clearLogs();
+        final String componentName = getComponentName(packageName, activityName);
+        executeShellCommand(getStartCommand(componentName, mode) + " --stack "
+                + FREEFORM_WORKSPACE_STACK_ID);
+        waitForResume(packageName, activityName);
+        Point topLeft = new Point(leftSide ? 0 : displaySize.x / 2, 0);
+        Point bottomRight = new Point(leftSide ? displaySize.x / 2 : displaySize.x, displaySize.y);
+        executeShellCommand(getResizeTaskCommand(getActivityTaskId(componentName), topLeft,
+                bottomRight));
+    }
+
     private void waitForResume(String packageName, String activityName) throws Exception {
         final String fullActivityName = packageName + "." + activityName;
         int retryCount = 3;
@@ -238,6 +272,7 @@
         builder.append("\nParsing adb shell am output: " );
         builder.append(output);
         CLog.i(builder.toString());
+        final Pattern pattern = Pattern.compile(String.format(TASK_REGEX_PATTERN_STRING, name));
         for (String line : output.split("\\n")) {
             final String truncatedLine;
             // Only look for the activity name before the "topActivity" string.
@@ -247,7 +282,7 @@
             } else {
                 truncatedLine = line;
             }
-            if (truncatedLine.contains(name)) {
+            if (pattern.matcher(truncatedLine).find()) {
                 return truncatedLine;
             }
         }
@@ -280,6 +315,12 @@
         return -1;
     }
 
+    private Point getDisplaySize() throws Exception {
+        final String output = executeShellCommand("wm size");
+        final String[] sizes = output.split(" ")[2].split("x");
+        return new Point(Integer.valueOf(sizes[0].trim()), Integer.valueOf(sizes[1].trim()));
+    }
+
     private Point getWindowCenter(String name) throws Exception {
         Point p1 = new Point();
         Point p2 = new Point();
@@ -343,8 +384,19 @@
             return;
         }
 
-        launchDockedActivity(mSourcePackageName, SOURCE_ACTIVITY_NAME, sourceMode);
-        launchFullscreenActivity(mTargetPackageName, TARGET_ACTIVITY_NAME, targetMode);
+        if (supportsSplitScreenMultiWindow()) {
+            launchDockedActivity(mSourcePackageName, SOURCE_ACTIVITY_NAME, sourceMode);
+            launchFullscreenActivity(mTargetPackageName, TARGET_ACTIVITY_NAME, targetMode);
+        } else if (supportsFreeformMultiWindow()) {
+            // Fallback to try to launch two freeform windows side by side.
+            Point displaySize = getDisplaySize();
+            launchFreeformActivity(mSourcePackageName, SOURCE_ACTIVITY_NAME, sourceMode,
+                    displaySize, true /* leftSide */);
+            launchFreeformActivity(mTargetPackageName, TARGET_ACTIVITY_NAME, targetMode,
+                    displaySize, false /* leftSide */);
+        } else {
+            return;
+        }
 
         clearLogs();
 
@@ -412,6 +464,14 @@
         }
     }
 
+    private boolean supportsSplitScreenMultiWindow() throws DeviceNotAvailableException {
+        return !executeShellCommand(AM_SUPPORTS_SPLIT_SCREEN_MULTIWINDOW).startsWith("false");
+    }
+
+    private boolean supportsFreeformMultiWindow() throws DeviceNotAvailableException {
+        return mDevice.hasFeature("feature:android.software.freeform_window_management");
+    }
+
     public void testCancelSoon() throws Exception {
         assertDropResult(CANCEL_SOON, REQUEST_NONE, RESULT_MISSING);
     }
diff --git a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
index 7d06682..1955483 100644
--- a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
+++ b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.os.Process;
 import android.util.Log;
 
@@ -99,16 +100,90 @@
             while ((work = params.dequeueWork()) != null) {
                 Log.i(TAG, "Received work #" + index + ": " + work.getIntent());
                 mReceivedWork.add(work.getIntent());
-                params.completeWork(work);
-                if (index < expectedWork.length && expectedWork[index].subitems != null) {
-                    final TestWorkItem[] sub = expectedWork[index].subitems;
-                    final JobInfo ji = expectedWork[index].jobInfo;
-                    final JobScheduler js = (JobScheduler) getSystemService(
-                            Context.JOB_SCHEDULER_SERVICE);
-                    for (int subi = 0; subi < sub.length; subi++) {
-                        js.enqueue(ji, new JobWorkItem(sub[subi].intent));
+
+                if (index < expectedWork.length) {
+                    TestWorkItem expected = expectedWork[index];
+                    int grantFlags = work.getIntent().getFlags();
+                    if (expected.requireUrisGranted != null) {
+                        for (int ui = 0; ui < expected.requireUrisGranted.length; ui++) {
+                            if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_GRANTED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Expected read permission but not granted: "
+                                                    + expected.requireUrisGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                            if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_GRANTED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Expected write permission but not granted: "
+                                                    + expected.requireUrisGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+                    if (expected.requireUrisNotGranted != null) {
+                        // XXX note no delay here, current impl will have fully revoked the
+                        // permission by the time we return from completing the last work.
+                        for (int ui = 0; ui < expected.requireUrisNotGranted.length; ui++) {
+                            if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisNotGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_DENIED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Not expected read permission but granted: "
+                                                    + expected.requireUrisNotGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                            if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisNotGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_DENIED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Not expected write permission but granted: "
+                                                    + expected.requireUrisNotGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                        }
                     }
                 }
+
+                params.completeWork(work);
+
+                if (index < expectedWork.length) {
+                    TestWorkItem expected = expectedWork[index];
+                    if (expected.subitems != null) {
+                        final TestWorkItem[] sub = expected.subitems;
+                        final JobInfo ji = expected.jobInfo;
+                        final JobScheduler js = (JobScheduler) getSystemService(
+                                Context.JOB_SCHEDULER_SERVICE);
+                        for (int subi = 0; subi < sub.length; subi++) {
+                            js.enqueue(ji, new JobWorkItem(sub[subi].intent));
+                        }
+                    }
+                }
+
+                index++;
             }
             Log.i(TAG, "Done with all work at #" + index);
             // We don't notifyExecution here because we want to make sure the job properly
@@ -130,17 +205,32 @@
         public final Intent intent;
         public final JobInfo jobInfo;
         public final TestWorkItem[] subitems;
+        public final Uri[] requireUrisGranted;
+        public final Uri[] requireUrisNotGranted;
 
         public TestWorkItem(Intent _intent) {
             intent = _intent;
             jobInfo = null;
             subitems = null;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
         }
 
         public TestWorkItem(Intent _intent, JobInfo _jobInfo, TestWorkItem[] _subitems) {
             intent = _intent;
             jobInfo = _jobInfo;
             subitems = _subitems;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, Uri[] _requireUrisGranted,
+                Uri[] _requireUrisNotGranted) {
+            intent = _intent;
+            jobInfo = null;
+            subitems = null;
+            requireUrisGranted = _requireUrisGranted;
+            requireUrisNotGranted = _requireUrisNotGranted;
         }
     }
 
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java
index 47089d4..03d941e 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java
@@ -73,7 +73,7 @@
         // Schedule the job, the system should now also be holding a URI grant for us.
         kTestEnvironment.setExpectedExecutions(1);
         mJobScheduler.schedule(mBuilder.setRequiresStorageNotLow(true)
-                .setClipData(mClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                .setClipData(mFirstClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
                         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION).build());
 
         // Remove the explicit grant, we should still have a grant due to the job.
@@ -105,7 +105,7 @@
     public void testClipDataGrant_Failed() throws Exception {
         try {
             mJobScheduler.schedule(mBuilder.setRequiresStorageNotLow(true)
-                    .setClipData(mClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                    .setClipData(mFirstClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION).build());
         } catch (SecurityException e) {
             return;
@@ -131,7 +131,7 @@
         // Schedule the job, the system should now also be holding a URI grant for us.
         kTestEnvironment.setExpectedExecutions(1);
         mJobScheduler.schedule(mBuilder.setMinimumLatency(60*60*1000)
-                .setClipData(mClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                .setClipData(mFirstClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
                         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION).build());
 
         // Remove the explicit grant, we should still have a grant due to the job.
@@ -145,7 +145,7 @@
 
         // Now reschedule the job to have it happen right now.
         mJobScheduler.schedule(mBuilder.setMinimumLatency(0)
-                .setClipData(mClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                .setClipData(mFirstClipData, Intent.FLAG_GRANT_READ_URI_PERMISSION
                         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION).build());
         assertTrue("Job with storage not low constraint did not fire when storage not low.",
                 kTestEnvironment.awaitExecution());
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
index c92e521..bcc1e08 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
@@ -17,7 +17,6 @@
 
 import android.annotation.TargetApi;
 import android.app.Instrumentation;
-import android.app.job.JobInfo;
 import android.app.job.JobScheduler;
 import android.content.ClipData;
 import android.content.ComponentName;
@@ -30,7 +29,6 @@
 import android.os.Bundle;
 import android.os.Process;
 import android.os.SystemClock;
-import android.test.AndroidTestCase;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
@@ -67,7 +65,10 @@
 
     Uri mFirstUri;
     Bundle mFirstUriBundle;
-    ClipData mClipData;
+    Uri mSecondUri;
+    Bundle mSecondUriBundle;
+    ClipData mFirstClipData;
+    ClipData mSecondClipData;
 
     boolean mStorageStateChanged;
 
@@ -82,8 +83,13 @@
         mFirstUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/foo");
         mFirstUriBundle = new Bundle();
         mFirstUriBundle.putParcelable("uri", mFirstUri);
-        mClipData = new ClipData("JobPerm", new String[] { "application/*" },
+        mSecondUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/bar");
+        mSecondUriBundle = new Bundle();
+        mSecondUriBundle.putParcelable("uri", mSecondUri);
+        mFirstClipData = new ClipData("JobPerm1", new String[] { "application/*" },
                 new ClipData.Item(mFirstUri));
+        mSecondClipData = new ClipData("JobPerm2", new String[] { "application/*" },
+                new ClipData.Item(mSecondUri));
         try {
             SystemUtil.runShellCommand(getInstrumentation(), "cmd activity set-inactive "
                     + mContext.getPackageName() + " false");
@@ -122,10 +128,23 @@
         getContext().sendBroadcast(EXPEDITE_STABLE_CHARGING);
     }
 
+    public void assertHasUriPermission(Uri uri, int grantFlags) {
+        if ((grantFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+            assertEquals(PackageManager.PERMISSION_GRANTED,
+                    getContext().checkUriPermission(uri, Process.myPid(),
+                            Process.myUid(), Intent.FLAG_GRANT_READ_URI_PERMISSION));
+        }
+        if ((grantFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+            assertEquals(PackageManager.PERMISSION_GRANTED,
+                    getContext().checkUriPermission(uri, Process.myPid(),
+                            Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
+        }
+    }
+
     void waitPermissionRevoke(Uri uri, int access, long timeout) {
         long startTime = SystemClock.elapsedRealtime();
         while (getContext().checkUriPermission(uri, Process.myPid(), Process.myUid(), access)
-                != PackageManager.PERMISSION_GRANTED) {
+                != PackageManager.PERMISSION_DENIED) {
             try {
                 Thread.sleep(50);
             } catch (InterruptedException e) {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java
index ad5a20f..402233b 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java
@@ -22,6 +22,7 @@
 import android.content.ContentProviderClient;
 import android.content.Intent;
 import android.jobscheduler.MockJobService.TestWorkItem;
+import android.net.Uri;
 
 import java.util.ArrayList;
 
@@ -44,13 +45,13 @@
         super.setUp();
 
         mBuilder = new JobInfo.Builder(ENQUEUE_WORK_JOB_ID, kJobServiceComponent);
-        //mProvider = getContext().getContentResolver().acquireContentProviderClient(mFirstUri);
+        mProvider = getContext().getContentResolver().acquireContentProviderClient(mFirstUri);
     }
 
     @Override
     public void tearDown() throws Exception {
         super.tearDown();
-        //mProvider.close();
+        mProvider.close();
         mJobScheduler.cancel(ENQUEUE_WORK_JOB_ID);
     }
 
@@ -74,19 +75,19 @@
         }
         for (int i = 0; i < received.size(); i++) {
             Intent work = received.get(i);
-            if (i >= expected.length) {
-                fail("Received more than " + expected.length + " work items, first extra is "
-                        + work);
-            }
-            if (!intentEquals(work, expectedArray.get(i).intent)) {
-                fail("Received work #" + i + " " + work + " but expected " + expected[i]);
-            }
             if (i < expected.length && expected[i].subitems != null) {
                 TestWorkItem[] sub = expected[i].subitems;
                 for (int j = 0; j < sub.length; j++) {
                     expectedArray.add(sub[j]);
                 }
             }
+            if (i >= expectedArray.size()) {
+                fail("Received more than " + expected.length + " work items, first extra is "
+                        + work);
+            }
+            if (!intentEquals(work, expectedArray.get(i).intent)) {
+                fail("Received work #" + i + " " + work + " but expected " + expected[i]);
+            }
         }
         if (received.size() < expected.length) {
             fail("Received only " + received.size() + " work items, but expected "
@@ -176,4 +177,61 @@
                 kTestEnvironment.awaitExecution());
         compareWork(work, kTestEnvironment.getLastReceivedWork());
     }
+
+    /**
+     * Test basic enqueueing batches of work.
+     */
+    public void testEnqueueMultipleUriGrantWork() throws Exception {
+        // Start out with storage low, so job is enqueued but not executed yet.
+        setStorageState(true);
+
+        // We need to get a permission grant so that we can grant it to ourself.
+        mProvider.call("grant", MY_PACKAGE, mFirstUriBundle);
+        mProvider.call("grant", MY_PACKAGE, mSecondUriBundle);
+        assertHasUriPermission(mFirstUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        assertHasUriPermission(mSecondUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+
+        Intent work1 = new Intent("work1");
+        work1.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        work1.setData(mFirstUri);
+        work1.setClipData(mSecondClipData);
+
+        Intent work2 = new Intent("work2");
+        work2.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        work2.setData(mFirstUri);
+
+        TestWorkItem[] work = new TestWorkItem[] {
+                new TestWorkItem(work1, new Uri[] { mFirstUri, mSecondUri}, new Uri[0]),
+                new TestWorkItem(work2, new Uri[] { mFirstUri }, new Uri[] { mSecondUri}) };
+        kTestEnvironment.setExpectedExecutions(1);
+        kTestEnvironment.setExpectedWork(work);
+        JobInfo ji = mBuilder.setOverrideDeadline(0).setRequiresStorageNotLow(true).build();
+        mJobScheduler.enqueue(ji, new JobWorkItem(work1));
+        mJobScheduler.enqueue(ji, new JobWorkItem(work2));
+
+        // Remove the explicit grant, we should still have a grant due to the job.
+        mProvider.call("revoke", MY_PACKAGE, mFirstUriBundle);
+        mProvider.call("revoke", MY_PACKAGE, mSecondUriBundle);
+        assertHasUriPermission(mFirstUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        assertHasUriPermission(mSecondUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+
+        kTestEnvironment.readyToWork();
+
+        // Now allow the job to run.
+        setStorageState(false);
+
+        assertTrue("Job with work enqueued did not fire.",
+                kTestEnvironment.awaitExecution());
+        compareWork(work, kTestEnvironment.getLastReceivedWork());
+
+        // And wait for everything to be cleaned up.
+        waitPermissionRevoke(mFirstUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 5000);
+        waitPermissionRevoke(mSecondUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 5000);
+    }
 }
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index 1185813..1979e97 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -23,7 +23,6 @@
 import android.test.InstrumentationTestCase;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
 
@@ -83,15 +82,6 @@
         assertFalse(mAccessibilityManager.removeTouchExplorationStateChangeListener(listener));
     }
 
-    public void testAddAndRemoveServiceStateChangeListener() throws Exception {
-        AccessibilityServicesStateChangeListener listener = () -> {
-            // Do Nothing
-        };
-        assertTrue(mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener));
-        assertTrue(mAccessibilityManager.removeAccessibilityServicesStateChangeListener(listener));
-        assertFalse(mAccessibilityManager.removeAccessibilityServicesStateChangeListener(listener));
-    }
-
     public void testIsTouchExplorationEnabled() throws Exception {
         new PollingCheck() {
             @Override
@@ -240,44 +230,6 @@
         waitForTouchExplorationEnabled();
     }
 
-    public void testServiceStateChanges_stateChangeListenersCalled() throws Exception {
-        final Object waitObject = new Object();
-        final AtomicBoolean listenerCalled = new AtomicBoolean(false);
-        final SpeakingAccessibilityService service =
-                SpeakingAccessibilityService.sConnectedInstance;
-        final AccessibilityServicesStateChangeListener listener = () -> {
-            synchronized (waitObject) {
-                listenerCalled.set(true);
-                waitObject.notifyAll();
-            }
-        };
-
-        mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener);
-        // Verify called on info change
-        final AccessibilityServiceInfo initialInfo = service.getServiceInfo();
-        AccessibilityServiceInfo tempInfo = service.getServiceInfo();
-        tempInfo.flags ^= AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME;
-        try {
-            service.setServiceInfo(tempInfo);
-            assertListenerCalled(listenerCalled, waitObject);
-        } finally {
-            service.setServiceInfo(initialInfo);
-        }
-
-        // Verify called on service disabled
-        listenerCalled.set(false);
-        ServiceControlUtils.turnAccessibilityOff(getInstrumentation());
-        assertListenerCalled(listenerCalled, waitObject);
-
-        // Verify called on service enabled
-        listenerCalled.set(false);
-        ServiceControlUtils.enableSpeakingAndVibratingServices(getInstrumentation());
-        assertListenerCalled(listenerCalled, waitObject);
-
-        mAccessibilityManager.removeAccessibilityServicesStateChangeListener(listener);
-
-    }
-
     private void assertListenerCalled(AtomicBoolean listenerCalled, Object waitObject)
             throws Exception {
         long timeoutTime = System.currentTimeMillis() + WAIT_FOR_ACCESSIBILITY_ENABLED_TIMEOUT;
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index 6e3d44992..32bf5a5 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -54,6 +54,7 @@
         <activity android:name=".DummyActivity"/>
         <activity android:name=".OutOfProcessLoginActivity"
             android:process="android.autofillservice.cts.outside"/>
+        <activity android:name=".FragmentContainerActivity" />
 
         <service
             android:name=".InstrumentedAutoFillService"
diff --git a/tests/autofillservice/res/layout/fragment_container.xml b/tests/autofillservice/res/layout/fragment_container.xml
new file mode 100644
index 0000000..156efad
--- /dev/null
+++ b/tests/autofillservice/res/layout/fragment_container.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  * Copyright (C) 2017 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.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/rootContainer" />
diff --git a/tests/autofillservice/res/layout/fragment_with_edittext.xml b/tests/autofillservice/res/layout/fragment_with_edittext.xml
new file mode 100644
index 0000000..e0d4584
--- /dev/null
+++ b/tests/autofillservice/res/layout/fragment_with_edittext.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  * Copyright (C) 2017 The Android Open Source Project
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <EditText android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/editText1" />
+
+    <EditText android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/editText2" />
+</LinearLayout>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
index f0b56d4..efc0b2c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
@@ -50,8 +50,8 @@
         });
         try {
             if (!latch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
-                throw new AssertionError(
-                        "action on UI thread timed out after " + timeoutMs + " ms");
+                throw new RetryableException("action on UI thread timed out after %d ms",
+                        timeoutMs);
             }
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index df61e37..d18e621 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -32,6 +32,7 @@
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.runner.RunWith;
 
 /**
@@ -48,6 +49,9 @@
 
     protected static final Replier sReplier = InstrumentedAutoFillService.getReplier();
 
+    @Rule
+    public final RetryRule mRetryRule = new RetryRule(2);
+
     @BeforeClass
     public static void removeLockScreen() {
         runShellCommand("input keyevent KEYCODE_WAKEUP");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFinishSessionTest.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFinishSessionTest.java
new file mode 100644
index 0000000..e4f081b
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFinishSessionTest.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+import static android.autofillservice.cts.FragmentContainerActivity.FRAGMENT_TAG;
+import static android.autofillservice.cts.Helper.FILL_TIMEOUT_MS;
+import static android.autofillservice.cts.Helper.eventually;
+import static android.autofillservice.cts.Helper.findNodeByResourceId;
+import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_GENERIC;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Fragment;
+import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.test.rule.ActivityTestRule;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests that the session finishes when the views and fragments go away
+ */
+public class AutoFinishSessionTest extends AutoFillServiceTestCase {
+    @Rule
+    public final ActivityTestRule<FragmentContainerActivity> mActivityRule =
+            new ActivityTestRule<>(FragmentContainerActivity.class);
+    private FragmentContainerActivity mActivity;
+    private EditText mEditText1;
+    private EditText mEditText2;
+    private Fragment mFragment;
+    private ViewGroup mParent;
+
+    @Before
+    public void initViews() {
+        mActivity = mActivityRule.getActivity();
+        mEditText1 = mActivity.findViewById(R.id.editText1);
+        mEditText2 = mActivity.findViewById(R.id.editText2);
+        mFragment = mActivity.getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
+        mParent = ((ViewGroup) mEditText1.getParent());
+
+        assertThat(mFragment).isNotNull();
+    }
+
+    private void removeViewsBaseTest(@NonNull Runnable firstRemove, @Nullable Runnable firstCheck,
+            @Nullable Runnable secondRemove, String... viewsToSave)
+            throws Exception {
+        enableService();
+        try {
+            // Set expectations.
+            sReplier.addResponse(new CannedFillResponse.Builder()
+                    .setSaveOnAllViewsInvisible(true)
+                    .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, viewsToSave).build());
+
+            // Trigger autofill
+            eventually(() -> {
+                mActivity.syncRunOnUiThread(() -> mEditText2.requestFocus());
+                mActivity.syncRunOnUiThread(() -> mEditText1.requestFocus());
+
+                try {
+                    sReplier.getNextFillRequest();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }, (int) (FILL_TIMEOUT_MS * 2));
+
+            sUiBot.assertNoDatasets();
+
+            // remove first set of views
+            mActivity.syncRunOnUiThread(() -> {
+                mEditText1.setText("editText1-filled");
+                mEditText2.setText("editText2-filled");
+            });
+            firstRemove.run();
+
+            // Check state between remove operations
+            if (firstCheck != null) {
+                firstCheck.run();
+            }
+
+            // remove second set of views
+            if (secondRemove != null) {
+                secondRemove.run();
+            }
+
+            // Save should be shows after all remove operations were executed
+            sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
+
+            SaveRequest saveRequest = sReplier.getNextSaveRequest();
+            for (String view : viewsToSave) {
+                assertThat(findNodeByResourceId(saveRequest.structure, view)
+                        .getAutofillValue().getTextValue().toString()).isEqualTo(view + "-filled");
+            }
+        } finally {
+            disableService();
+        }
+    }
+
+    @Test
+    public void removeBothViewsToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(
+                        () -> ((ViewGroup) mEditText1.getParent()).removeView(mEditText1)),
+                () -> sUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_GENERIC),
+                () -> mActivity.syncRunOnUiThread(
+                        () -> ((ViewGroup) mEditText2.getParent()).removeView(mEditText2)),
+                "editText1", "editText2");
+    }
+
+    @Test
+    public void removeOneViewToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(() -> {
+                    // Do not trigger new partition when switching to editText2
+                    mEditText2.setFocusable(false);
+
+                    mParent.removeView(mEditText1);
+                }),
+                null,
+                null,
+                "editText1");
+    }
+
+    @Test
+    public void hideOneViewToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(
+                        () -> mEditText1.setVisibility(ViewGroup.INVISIBLE)),
+                null,
+                null,
+                "editText1");
+    }
+
+    @Test
+    public void removeFragmentToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(
+                        () -> mActivity.getFragmentManager().beginTransaction().remove(
+                                mFragment).commitNow()),
+                null,
+                null,
+                "editText1", "editText2");
+    }
+
+    @Test
+    public void removeParentToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(
+                        () -> ((ViewGroup) mParent.getParent()).removeView(mParent)),
+                null,
+                null,
+                "editText1", "editText2");
+    }
+
+    @Test
+    public void hideParentToFinishSession() throws Exception {
+        removeViewsBaseTest(
+                () -> mActivity.syncRunOnUiThread(() -> mParent.setVisibility(ViewGroup.INVISIBLE)),
+                null,
+                null,
+                "editText1", "editText2");
+    }
+
+    /**
+     * An activity that is currently getting autofilled might go into the background. While the
+     * tracked views are not visible on the screen anymore, this should not trigger a save.
+     */
+    public void activityToBackgroundShouldNotTriggerSave(@Nullable Runnable removeInBackGround,
+            @Nullable Runnable removeInForeGroup) throws Exception {
+        enableService();
+        try {
+            // Set expectations.
+            sReplier.addResponse(new CannedFillResponse.Builder()
+                    .setSaveOnAllViewsInvisible(true)
+                    .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, "editText1").build());
+
+            // Trigger autofill
+            eventually(() -> {
+                mActivity.syncRunOnUiThread(() -> mEditText2.requestFocus());
+                mActivity.syncRunOnUiThread(() -> mEditText1.requestFocus());
+
+                try {
+                    sReplier.getNextFillRequest();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }, (int) (FILL_TIMEOUT_MS * 2));
+
+            sUiBot.assertNoDatasets();
+
+            mActivity.syncRunOnUiThread(() -> {
+                mEditText1.setText("editText1-filled");
+                mEditText2.setText("editText2-filled");
+            });
+
+            // Start activity on top
+            mActivity.startActivity(new Intent(getContext(),
+                    ManualAuthenticationActivity.class));
+            mActivity.waitUntilStopped();
+
+            if (removeInBackGround != null) {
+                removeInBackGround.run();
+            }
+
+            sUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_GENERIC);
+
+            // Remove previously started activity from top
+            sUiBot.selectById("android.autofillservice.cts:id/button");
+            mActivity.waitUntilResumed();
+
+            if (removeInForeGroup != null) {
+                sUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_GENERIC);
+
+                removeInForeGroup.run();
+            }
+
+            // Save should be shows after all remove operations were executed
+            sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
+
+            SaveRequest saveRequest = sReplier.getNextSaveRequest();
+            assertThat(findNodeByResourceId(saveRequest.structure, "editText1")
+                    .getAutofillValue().getTextValue().toString()).isEqualTo("editText1-filled");
+        } finally {
+            disableService();
+        }
+    }
+
+    @Test
+    public void removeViewInBackground() throws Exception {
+        activityToBackgroundShouldNotTriggerSave(
+                () -> mActivity.syncRunOnUiThread(() -> {
+                    // Do not trigger new partition when switching to editText2
+                    mEditText2.setFocusable(false);
+
+                    mParent.removeView(mEditText1);
+                }),
+                null);
+    }
+
+    @Test
+    public void hideViewInBackground() throws Exception {
+        activityToBackgroundShouldNotTriggerSave(
+                () -> mActivity.syncRunOnUiThread(() -> {
+                    // Do not trigger new partition when switching to editText2
+                    mEditText2.setFocusable(false);
+
+                    mEditText1.setVisibility(ViewGroup.INVISIBLE);
+                }),
+                null);
+    }
+
+    @Test
+    public void hideParentInBackground() throws Exception {
+        activityToBackgroundShouldNotTriggerSave(
+                () -> mActivity.syncRunOnUiThread(() -> mParent.setVisibility(ViewGroup.INVISIBLE)),
+                null);
+    }
+
+    @Test
+    public void removeParentInBackground() throws Exception {
+        activityToBackgroundShouldNotTriggerSave(
+                () -> mActivity.syncRunOnUiThread(
+                        () -> ((ViewGroup) mParent.getParent()).removeView(mParent)),
+                null);
+    }
+
+    @Test
+    public void removeViewAfterBackground() throws Exception {
+        activityToBackgroundShouldNotTriggerSave(
+                () -> mActivity.syncRunOnUiThread(() -> {
+                    // Do not trigger new fill request when closing activity
+                    mEditText1.setFocusable(false);
+                    mEditText2.setFocusable(false);
+                }),
+                () -> mActivity.syncRunOnUiThread(() -> {
+                    mParent.removeView(mEditText1);
+                }));
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index 2fa29ce..0ceab53 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -66,6 +66,7 @@
     private final String[] mAuthenticationIds;
     private final CharSequence mNegativeActionLabel;
     private final IntentSender mNegativeActionListener;
+    private final boolean mSaveOnAllViewsInvisible;
 
     private CannedFillResponse(Builder builder) {
         mDatasets = builder.mDatasets;
@@ -79,6 +80,7 @@
         mAuthenticationIds = builder.mAuthenticationIds;
         mNegativeActionLabel = builder.mNegativeActionLabel;
         mNegativeActionListener = builder.mNegativeActionListener;
+        mSaveOnAllViewsInvisible = builder.mSaveOnAllViewsInvisible;
     }
 
     /**
@@ -100,9 +102,18 @@
                 builder.addDataset(dataset);
             }
         }
-        if (mRequiredSavableIds != null) {
-            final SaveInfo.Builder saveInfo = new SaveInfo.Builder(mSaveType,
-                    getAutofillIds(structure, mRequiredSavableIds));
+        if (mRequiredSavableIds != null || mSaveOnAllViewsInvisible) {
+            final SaveInfo.Builder saveInfo;
+
+            if (mRequiredSavableIds == null) {
+                saveInfo = new SaveInfo.Builder(mSaveType, null);
+            } else {
+                saveInfo = new SaveInfo.Builder(mSaveType,
+                        getAutofillIds(structure, mRequiredSavableIds));
+            }
+
+            saveInfo.setSaveOnAllViewsInvisible(mSaveOnAllViewsInvisible);
+
             if (mOptionalSavableIds != null) {
                 saveInfo.setOptionalIds(getAutofillIds(structure, mOptionalSavableIds));
             }
@@ -126,6 +137,7 @@
         return "CannedFillResponse: [datasets=" + mDatasets
                 + ", requiredSavableIds=" + Arrays.toString(mRequiredSavableIds)
                 + ", optionalSavableIds=" + Arrays.toString(mOptionalSavableIds)
+                + ", saveOnAllViewsInvisible=" + mSaveOnAllViewsInvisible
                 + ", saveDescription=" + mSaveDescription
                 + ", hasPresentation=" + (mPresentation != null)
                 + ", hasAuthentication=" + (mAuthentication != null)
@@ -145,6 +157,7 @@
         private String[] mAuthenticationIds;
         private CharSequence mNegativeActionLabel;
         private IntentSender mNegativeActionListener;
+        private boolean mSaveOnAllViewsInvisible;
 
         public Builder addDataset(CannedDataset dataset) {
             mDatasets.add(dataset);
@@ -161,6 +174,14 @@
         }
 
         /**
+         * Sets the saveOnAllViewsInvisible flag
+         */
+        public Builder setSaveOnAllViewsInvisible(boolean saveOnAllViewsInvisible) {
+            mSaveOnAllViewsInvisible = saveOnAllViewsInvisible;
+            return this;
+        }
+
+        /**
          * Sets the optional savable ids based on they {@code resourceId}.
          */
         public Builder setOptionalSavableIds(String... ids) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FragmentContainerActivity.java b/tests/autofillservice/src/android/autofillservice/cts/FragmentContainerActivity.java
new file mode 100644
index 0000000..7be4496
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/FragmentContainerActivity.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity containing an fragment
+ */
+public class FragmentContainerActivity extends AbstractAutoFillActivity {
+    static final String FRAGMENT_TAG =
+            FragmentContainerActivity.class.getName() + "#FRAGMENT_TAG";
+    private CountDownLatch mResumed = new CountDownLatch(1);
+    private CountDownLatch mStopped = new CountDownLatch(0);
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.fragment_container);
+
+        // have to manually add fragment as we cannot remove it otherwise
+        getFragmentManager().beginTransaction().add(R.id.rootContainer,
+                new FragmentWithEditText(), FRAGMENT_TAG).commitNow();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        mStopped = new CountDownLatch(1);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        mResumed.countDown();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        mResumed = new CountDownLatch(1);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+
+        mStopped.countDown();
+    }
+
+    public boolean waitUntilResumed() throws InterruptedException {
+        return mResumed.await(Helper.UI_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+    }
+
+    public boolean waitUntilStopped() throws InterruptedException {
+        return mStopped.await(Helper.UI_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FragmentWithEditText.java b/tests/autofillservice/src/android/autofillservice/cts/FragmentWithEditText.java
new file mode 100644
index 0000000..963daff
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/FragmentWithEditText.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+import android.support.annotation.Nullable;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+/**
+ * A fragment with containing a single {@link EditText}
+ */
+public class FragmentWithEditText extends Fragment {
+    @Override
+    @Nullable public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_with_edittext, null);
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java b/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
index 6df6f10..c9b6d30 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
@@ -113,7 +113,7 @@
         onCell(row, column, (c) -> queue.offer(c.getText().toString()));
         final String text = queue.poll(100, TimeUnit.MILLISECONDS);
         if (text == null) {
-            throw new AssertionError("text not set in 100ms");
+            throw new RetryableException("text not set in 100ms");
         }
         return text;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index c78a6e1..bd69587 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -107,7 +107,7 @@
         final String state = sConnectionStates.poll(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
         if (state == null) {
             dumpAutofillService();
-            throw new AssertionError("not connected in " + CONNECTION_TIMEOUT_MS + " ms");
+            throw new RetryableException("not connected in %d ms", CONNECTION_TIMEOUT_MS);
         }
         assertWithMessage("Invalid connection state").that(state).isEqualTo(STATE_CONNECTED);
     }
@@ -122,7 +122,7 @@
         final String state = sConnectionStates.poll(2 * IDLE_UNBIND_TIMEOUT_MS,
                 TimeUnit.MILLISECONDS);
         if (state == null) {
-            throw new AssertionError("not disconnected in " + IDLE_UNBIND_TIMEOUT_MS + " ms");
+            throw new RetryableException("not disconnected in %d ms", IDLE_UNBIND_TIMEOUT_MS);
         }
         assertWithMessage("Invalid connection state").that(state).isEqualTo(STATE_DISCONNECTED);
     }
@@ -221,8 +221,8 @@
         FillRequest getNextFillRequest() throws InterruptedException {
             final FillRequest request = mFillRequests.poll(FILL_TIMEOUT_MS, TimeUnit.MILLISECONDS);
             if (request == null) {
-                throw new AssertionError(
-                        "onFillRequest() not called in " + FILL_TIMEOUT_MS + " ms");
+                throw new RetryableException("onFillRequest() not called in %s ms",
+                        FILL_TIMEOUT_MS);
             }
             return request;
         }
@@ -245,8 +245,8 @@
         SaveRequest getNextSaveRequest() throws InterruptedException {
             final SaveRequest request = mSaveRequests.poll(SAVE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
             if (request == null) {
-                throw new AssertionError(
-                        "onSaveRequest() not called in " + SAVE_TIMEOUT_MS + " ms");
+                throw new RetryableException(
+                        "onSaveRequest() not called in %d ms", SAVE_TIMEOUT_MS);
             }
             return request;
         }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ManualAuthenticationActivity.java b/tests/autofillservice/src/android/autofillservice/cts/ManualAuthenticationActivity.java
index c2af4cc1..32844d4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ManualAuthenticationActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ManualAuthenticationActivity.java
@@ -49,25 +49,24 @@
         setContentView(R.layout.single_button_activity);
 
         findViewById(R.id.button).setOnClickListener((v) -> {
-            // We should get the assist structure
             AssistStructure structure = getIntent().getParcelableExtra(
                     AutofillManager.EXTRA_ASSIST_STRUCTURE);
-            assertWithMessage("structure not called").that(structure).isNotNull();
+            if (structure != null) {
+                Parcelable result;
+                if (sResponse != null) {
+                    result = sResponse.asFillResponse(structure);
+                } else if (sDataset != null) {
+                    result = sDataset.asDataset(structure);
+                } else {
+                    throw new IllegalStateException("no dataset or response");
+                }
 
-            Parcelable result = null;
-            if (sResponse != null) {
-                result = sResponse.asFillResponse(structure);
-            } else if (sDataset != null) {
-                result = sDataset.asDataset(structure);
-            } else {
-                throw new IllegalStateException("no dataset or response");
+                // Pass on the auth result
+                Intent intent = new Intent();
+                intent.putExtra(AutofillManager.EXTRA_AUTHENTICATION_RESULT, result);
+                setResult(RESULT_OK, intent);
             }
 
-            // Pass on the auth result
-            Intent intent = new Intent();
-            intent.putExtra(AutofillManager.EXTRA_AUTHENTICATION_RESULT, result);
-            setResult(RESULT_OK, intent);
-
             // Done
             finish();
         });
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java b/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
index 13887fa..48b0c2f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
@@ -50,7 +50,7 @@
     MyEvent getEvent() throws InterruptedException {
         final MyEvent event = mEvents.poll(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
         if (event == null) {
-            throw new AssertionError("no event in " + CONNECTION_TIMEOUT_MS + " ms");
+            throw new RetryableException("no event in %d ms", CONNECTION_TIMEOUT_MS);
         }
         return event;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryRule.java b/tests/autofillservice/src/android/autofillservice/cts/RetryRule.java
new file mode 100644
index 0000000..a4db0f4
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/RetryRule.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+import android.util.Log;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that retry tests when they fail due to a {@link RetryableException}.
+ */
+public class RetryRule implements TestRule {
+
+    private static final String TAG = "RetryRule";
+    private final int mMaxAttempts;
+
+    public RetryRule(int maxAttempts) {
+        if (maxAttempts < 2) {
+            throw new IllegalArgumentException(
+                    "Must retry at least once; otherwise, what's the point?");
+        }
+        mMaxAttempts = maxAttempts;
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                RetryableException caught = null;
+                for (int i = 1; i <= mMaxAttempts; i++) {
+                    try {
+                        base.evaluate();
+                        return;
+                    } catch (RetryableException e) {
+                        caught = e;
+                        Log.w(TAG,
+                                description.getDisplayName() + ": attempt " + i + " failed: " + e);
+                    }
+                }
+                throw caught;
+            }
+        };
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java b/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
new file mode 100644
index 0000000..50ae8c8
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.Statement;
+
+@RunWith(AndroidJUnit4.class)
+public class RetryRuleTest {
+
+    private final Description mDescription = Description.createSuiteDescription("Whatever");
+
+    private static final RetryableException sRetryableException =
+            new RetryableException("Y U NO RETRY?");
+
+    private static class RetryableStatement extends Statement {
+        private final int mNumberFailures;
+        private int mNumberCalls;
+
+        RetryableStatement(int numberFailures) {
+            mNumberFailures = numberFailures;
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            mNumberCalls ++;
+            if (mNumberCalls <= mNumberFailures) {
+                throw sRetryableException;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "RetryableStatement: failures=" + mNumberFailures + ", calls=" + mNumberCalls;
+        }
+    }
+
+    @Test
+    public void testPass() throws Throwable {
+        final RetryRule rule = new RetryRule(2);
+        rule.apply(new RetryableStatement(1), mDescription).evaluate();
+    }
+
+    @Test
+    public void testFail() throws Throwable {
+        final RetryRule rule = new RetryRule(2);
+        try {
+            rule.apply(new RetryableStatement(2), mDescription).evaluate();
+            throw new AssertionError("2ND CALL, Y U NO FAIL?");
+        } catch (RetryableException e) {
+            assertThat(e).isSameAs(sRetryableException);
+        }
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryableException.java b/tests/autofillservice/src/android/autofillservice/cts/RetryableException.java
new file mode 100644
index 0000000..9b9d651
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/RetryableException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.autofillservice.cts;
+
+/**
+ * Exception that cause the {@link RetryRule} to re-try a test.
+ */
+public class RetryableException extends RuntimeException {
+
+    public RetryableException(String msg) {
+        super(msg);
+    }
+
+    public RetryableException(String format, Object...args) {
+        this(String.format(format, args));
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 30dae0e..deba8b7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -92,7 +92,7 @@
             // not showing...
             return;
         }
-        throw new AssertionError("floating ui is shown: " + ui);
+        throw new RetryableException("floating ui is shown: %s", ui);
     }
 
     /**
@@ -219,7 +219,7 @@
             // not showing (in which case it wouldn't need a type as parameter).
             return;
         }
-        throw new AssertionError("snack bar is showing");
+        throw new RetryableException("snack bar is showing");
     }
 
     private String getSaveTypeString(int type) {
@@ -335,7 +335,7 @@
             }
             menuNames.append("'").append(menuName).append("' ");
         }
-        throw new AssertionError("no '" + expectedText + "' on " + menuNames);
+        throw new RetryableException("no '%s' on '%s'", expectedText, menuNames);
     }
 
     /**
@@ -382,8 +382,8 @@
             }
             SystemClock.sleep(napTime);
         }
-        throw new AssertionError("Object with selector " + selector + " not found in "
-                + mTimeout + " ms");
+        throw new RetryableException("Object with selector '%s' not found in %d ms",
+                selector, mTimeout);
     }
 
     /**
@@ -412,9 +412,10 @@
             }
             SystemClock.sleep(napTime);
         }
-        throw new AssertionError("Objects with selector " + selector + " not found in "
-                + mTimeout + " ms");
+        throw new RetryableException("Objects with selector '%s' not found in %d ms",
+                selector, mTimeout);
     }
+
     private UiObject2 findDatasetPicker() {
         final UiObject2 picker = waitForObject(By.res("android", RESOURCE_ID_DATASET_PICKER));
 
@@ -436,6 +437,6 @@
                 return;
             }
         }
-        throw new AssertionError("Title (" + expectedTitle + ") not found for " + object);
+        throw new RetryableException("Title '%s' not found for %s", expectedTitle, object);
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
index 6b97195..0344830 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
@@ -127,7 +127,7 @@
         try {
             VirtualContainerView.assertHtmlInfo(username);
             VirtualContainerView.assertHtmlInfo(password);
-        } catch (AssertionError e) {
+        } catch (AssertionError | RuntimeException e) {
             dumpStructure("HtmlInfo failed", request.structure);
             throw e;
         }
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 6ae3011..b51e338 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -1649,10 +1649,6 @@
                     checkMeteringRect(afRegions);
                 }
             }
-            // ZSL must default to OFF
-            if (request.get(CONTROL_ENABLE_ZSL) != null) {
-                mCollector.expectKeyValueEquals(request, CONTROL_ENABLE_ZSL, false);
-            }
         }
 
         // Sensor settings.
@@ -1915,6 +1911,13 @@
             }
         }
 
+        // Enable ZSL
+        if (template != CameraDevice.TEMPLATE_STILL_CAPTURE) {
+            if (mStaticInfo.areKeysAvailable(CONTROL_ENABLE_ZSL)) {
+                    mCollector.expectKeyValueEquals(request, CONTROL_ENABLE_ZSL, false);
+            }
+        }
+
         int[] outputFormats = mStaticInfo.getAvailableFormats(
                 StaticMetadata.StreamDirection.Output);
         boolean supportRaw = false;
diff --git a/tests/fragment/src/android/fragment/cts/FragmentAnimatorTest.java b/tests/fragment/src/android/fragment/cts/FragmentAnimatorTest.java
index b5e9cad..f234155 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentAnimatorTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentAnimatorTest.java
@@ -59,11 +59,8 @@
     public ActivityTestRule<FragmentTestActivity> mActivityRule =
             new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
 
-    private Instrumentation mInstrumentation;
-
     @Before
     public void setupContainer() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
     }
 
@@ -365,12 +362,12 @@
                 .replace(R.id.fragmentContainer, fragment2, "2")
                 .addToBackStack(null)
                 .commit();
-        mInstrumentation.runOnMainSync(fm1::executePendingTransactions);
+        mActivityRule.runOnUiThread(fm1::executePendingTransactions);
         FragmentTestUtil.waitForExecution(mActivityRule);
 
         fm1.popBackStack();
 
-        mInstrumentation.runOnMainSync(fm1::executePendingTransactions);
+        mActivityRule.runOnUiThread(fm1::executePendingTransactions);
         FragmentTestUtil.waitForExecution(mActivityRule);
         // Now fragment2 should be animating away
         assertFalse(fragment2.isAdded());
diff --git a/tests/fragment/src/android/fragment/cts/FragmentExecuteTests.java b/tests/fragment/src/android/fragment/cts/FragmentExecuteTests.java
index 7d65b8c..6e6cda9 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentExecuteTests.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentExecuteTests.java
@@ -41,11 +41,8 @@
     public ActivityTestRule<FragmentTestActivity> mActivityRule =
             new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
 
-    private Instrumentation mInstrumentation;
-
     @Before
     public void setupContentView() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
     }
 
@@ -58,7 +55,7 @@
         final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
         final StrictViewFragment fragment = new StrictViewFragment();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 fm.beginTransaction()
diff --git a/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java b/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
index f91eb65..bbd8d10 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
@@ -15,11 +15,11 @@
  */
 package android.fragment.cts;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.app.FragmentManager;
-import android.app.Instrumentation;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -39,14 +39,12 @@
 
     private ViewGroup mContainer;
     private FragmentManager mFM;
-    private Instrumentation mInstrumentation;
 
     @Before
     public void setup() {
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
         mContainer = (ViewGroup) mActivityRule.getActivity().findViewById(R.id.fragmentContainer);
         mFM = mActivityRule.getActivity().getFragmentManager();
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
     }
 
     // Test that when you add and replace a fragment that only the replace's add
@@ -55,7 +53,7 @@
     public void addReplace() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
         final StrictViewFragment fragment2 = new StrictViewFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().add(R.id.fragmentContainer, fragment1).addToBackStack(null).commit();
@@ -69,7 +67,7 @@
         assertEquals(0, fragment1.onCreateViewCount);
         FragmentTestUtil.assertChildren(mContainer, fragment2);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.popBackStack();
@@ -92,7 +90,7 @@
         FragmentTestUtil.assertChildren(mContainer, fragment1);
 
         // Now pop and add
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.popBackStack();
@@ -116,7 +114,7 @@
     public void middlePop() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
         final CountCallsFragment fragment2 = new CountCallsFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -146,7 +144,7 @@
     public void optimizeRemove() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
         final int[] id = new int[1];
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 id[0] = mFM.beginTransaction()
@@ -186,7 +184,7 @@
         FragmentTestUtil.executePendingTransactions(mActivityRule);
         assertEquals(1, fragment1.onCreateViewCount);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -224,7 +222,7 @@
         assertEquals(1, fragment1.onAttachCount);
         FragmentTestUtil.assertChildren(mContainer, fragment1);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().detach(fragment1).addToBackStack(null).commit();
@@ -274,7 +272,7 @@
         assertEquals(0, fragment1.onCreateViewCount);
         FragmentTestUtil.assertChildren(mContainer);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().attach(fragment1).addToBackStack(null).commit();
@@ -318,7 +316,7 @@
         assertEquals(1, fragment1.onHideCount);
         FragmentTestUtil.assertChildren(mContainer, fragment1);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -353,7 +351,7 @@
         assertEquals(0, fragment1.onShowCount);
         assertEquals(1, fragment1.onHideCount);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().show(fragment1).addToBackStack(null).commit();
@@ -373,7 +371,7 @@
         assertEquals(0, fragment1.onShowCount);
         assertEquals(1, fragment1.onHideCount);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().show(fragment1).addToBackStack(null).commit();
@@ -408,7 +406,7 @@
         assertEquals(0, fragment1.onHideCount);
         FragmentTestUtil.assertChildren(mContainer, fragment1);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction().hide(fragment1).addToBackStack(null).commit();
@@ -445,7 +443,7 @@
 
         final CountCallsFragment fragment2 = new CountCallsFragment();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -470,7 +468,7 @@
     @Test
     public void addPopBackStack() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -493,7 +491,7 @@
     public void popNonBackStack() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
         final CountCallsFragment fragment2 = new CountCallsFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
@@ -519,7 +517,7 @@
     public void noOptimization() throws Throwable {
         final CountCallsFragment fragment1 = new CountCallsFragment();
         final CountCallsFragment fragment2 = new CountCallsFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFM.beginTransaction()
diff --git a/tests/fragment/src/android/fragment/cts/FragmentTestUtil.java b/tests/fragment/src/android/fragment/cts/FragmentTestUtil.java
index c175164..62c4906 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentTestUtil.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentTestUtil.java
@@ -23,10 +23,8 @@
 import android.app.FragmentController;
 import android.app.FragmentManager;
 import android.app.FragmentManagerNonConfig;
-import android.app.Instrumentation;
 import android.os.Looper;
 import android.os.Parcelable;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Pair;
 import android.view.View;
@@ -42,9 +40,14 @@
         // the UI thread and then the execution will be added onto the queue after that.
         // The two-cycle wait makes sure fragments have the opportunity to complete both
         // before returning.
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        instrumentation.runOnMainSync(() -> {});
-        instrumentation.runOnMainSync(() -> {});
+        try {
+            rule.runOnUiThread(() -> {
+            });
+            rule.runOnUiThread(() -> {
+            });
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
     }
 
     private static void runOnUiThreadRethrow(ActivityTestRule<? extends Activity> rule,
diff --git a/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java b/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
index 43a9590..7421377 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
@@ -15,7 +15,8 @@
  */
 package android.fragment.cts;
 
-import static junit.framework.Assert.*;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.fail;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -23,22 +24,20 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 
-import com.android.compatibility.common.util.transition.TargetTracking;
-import com.android.compatibility.common.util.transition.TrackingTransition;
-
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
-import android.app.Instrumentation;
 import android.app.SharedElementCallback;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.transition.TransitionSet;
 import android.view.View;
 
+import com.android.compatibility.common.util.transition.TargetTracking;
+import com.android.compatibility.common.util.transition.TrackingTransition;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -68,7 +67,6 @@
     public ActivityTestRule<FragmentTestActivity> mActivityRule =
             new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
 
-    private Instrumentation mInstrumentation;
     private FragmentManager mFragmentManager;
 
     public FragmentTransitionTest(final boolean optimize) {
@@ -77,7 +75,6 @@
 
     @Before
     public void setup() throws Throwable {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mFragmentManager = mActivityRule.getActivity().getFragmentManager();
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
     }
@@ -163,7 +160,7 @@
         final TransitionFragment fragment2 = new TransitionFragment();
         fragment2.setLayoutId(R.layout.scene2);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 mFragmentManager.beginTransaction()
@@ -966,7 +963,7 @@
         final View startRed = findRed();
         final Rect startSharedRect = getBoundsOnScreen(startBlue);
 
-        mInstrumentation.runOnMainSync(() -> {
+        mActivityRule.runOnUiThread(() -> {
             for (int i = 0; i < numPops; i++) {
                 mFragmentManager.popBackStack();
             }
diff --git a/tests/fragment/src/android/fragment/cts/FragmentViewTests.java b/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
index 6f96811..e9c80e0 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
@@ -46,13 +46,6 @@
     public ActivityTestRule<FragmentTestActivity> mActivityRule =
             new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
 
-    private Instrumentation mInstrumentation;
-
-    @Before
-    public void setupInstrumentation() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-    }
-
     // Test that adding a fragment adds the Views in the proper order. Popping the back stack
     // should remove the correct Views.
     @Test
@@ -156,7 +149,7 @@
         fm.beginTransaction().add(R.id.fragmentContainer, fragment1).commit();
         FragmentTestUtil.executePendingTransactions(mActivityRule);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 try {
@@ -917,7 +910,7 @@
 
         final StrictViewFragment fragment2 = new StrictViewFragment();
         final StrictViewFragment fragment3 = new StrictViewFragment();
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 fm.popBackStack();
diff --git a/tests/fragment/src/android/fragment/cts/PostponedTransitionTest.java b/tests/fragment/src/android/fragment/cts/PostponedTransitionTest.java
index a3c43aa..2b89bc2 100644
--- a/tests/fragment/src/android/fragment/cts/PostponedTransitionTest.java
+++ b/tests/fragment/src/android/fragment/cts/PostponedTransitionTest.java
@@ -26,10 +26,8 @@
 import android.app.FragmentController;
 import android.app.FragmentManager;
 import android.app.FragmentManagerNonConfig;
-import android.app.Instrumentation;
 import android.os.Bundle;
 import android.os.Parcelable;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -50,12 +48,10 @@
     public ActivityTestRule<FragmentTestActivity> mActivityRule =
             new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
 
-    private Instrumentation mInstrumentation;
     private PostponedFragment1 mBeginningFragment;
 
     @Before
     public void setupContainer() throws Throwable {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
         final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
         mBeginningFragment = new PostponedFragment1();
@@ -119,7 +115,7 @@
         final int commit[] = new int[1];
         // Need to run this on the UI thread so that the transaction doesn't start
         // between the two
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 commit[0] = fm.beginTransaction()
@@ -489,7 +485,7 @@
         final TransitionFragment fragment4 = new PostponedFragment2();
         final StrictFragment strictFragment2 = new StrictFragment();
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 fm.beginTransaction()
@@ -539,7 +535,7 @@
 
         final View startBlue2 = fragment2.getView().findViewById(R.id.blueSquare);
 
-        mInstrumentation.runOnMainSync(new Runnable() {
+        mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 fm.beginTransaction()
@@ -664,7 +660,7 @@
         assertTrue(fragment2.isAdded());
         assertTrue(fragment2.getView().isAttachedToWindow());
 
-        mInstrumentation.runOnMainSync(() -> {
+        mActivityRule.runOnUiThread(() -> {
             assertTrue(fm2.popBackStackImmediate());
         });
 
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
index b660559..aea201c 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -35,6 +35,7 @@
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -197,6 +198,7 @@
         }
     }
 
+    @LargeTest
     @Test
     public void testDecodeRegionInputStream() throws IOException {
         Options opts = new BitmapFactory.Options();
@@ -223,6 +225,7 @@
         }
     }
 
+    @LargeTest
     @Test
     public void testDecodeRegionInputStreamInBitmap() throws IOException {
         Options opts = new BitmapFactory.Options();
@@ -254,6 +257,7 @@
         }
     }
 
+    @LargeTest
     @Test
     public void testDecodeRegionByteArray() throws IOException {
         Options opts = new BitmapFactory.Options();
@@ -281,6 +285,7 @@
         }
     }
 
+    @LargeTest
     @Test
     public void testDecodeRegionStringAndFileDescriptor() throws IOException {
         Options opts = new BitmapFactory.Options();
@@ -353,6 +358,7 @@
     //     (2) The width, height, and Config of inBitmap are never changed.
     //     (3) All of the pixels decoded into inBitmap exactly match the pixels
     //         of a decode where inBitmap is NULL.
+    @LargeTest
     @Test
     public void testInBitmapReuse() throws IOException {
         Options defaultOpts = new BitmapFactory.Options();
@@ -483,6 +489,31 @@
     }
 
     @Test
+    public void testReusedColorSpace() throws IOException {
+        Bitmap b = Bitmap.createBitmap(SMALL_TILE_SIZE, SMALL_TILE_SIZE, Config.ARGB_8888,
+                false, ColorSpace.get(ColorSpace.Named.ADOBE_RGB));
+
+        Options opts = new BitmapFactory.Options();
+        opts.inBitmap = b;
+
+        // sRGB
+        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(
+                obtainInputStream(ASSET_NAMES[3]), false);
+        Bitmap region = decoder.decodeRegion(
+                new Rect(0, 0, SMALL_TILE_SIZE, SMALL_TILE_SIZE), opts);
+        decoder.recycle();
+
+        assertEquals(ColorSpace.get(ColorSpace.Named.SRGB), region.getColorSpace());
+
+        // DisplayP3
+        decoder = BitmapRegionDecoder.newInstance(obtainInputStream(ASSET_NAMES[1]), false);
+        region = decoder.decodeRegion(new Rect(0, 0, SMALL_TILE_SIZE, SMALL_TILE_SIZE), opts);
+        decoder.recycle();
+
+        assertEquals(ColorSpace.get(ColorSpace.Named.DISPLAY_P3), region.getColorSpace());
+    }
+
+    @Test
     public void testInColorSpace() throws IOException {
         Options opts = new BitmapFactory.Options();
         for (int i = 0; i < NUM_TEST_IMAGES; ++i) {
diff --git a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
index f5c7aa3..22fa7c3 100644
--- a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
@@ -28,7 +28,7 @@
 import android.graphics.Movie;
 import android.graphics.Paint;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.WidgetTestUtils;
@@ -44,7 +44,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-@MediumTest
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class MovieTest {
     private final int MOVIE = R.drawable.animated;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
index 1c9f9b3..29da030 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
@@ -30,7 +30,9 @@
 import android.graphics.cts.R;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 import android.view.View;
@@ -50,7 +52,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-@MediumTest
+@LargeTest
 @RunWith(Parameterized.class)
 public class AnimatedVectorDrawableParameterizedTest {
     @Rule
@@ -183,6 +185,7 @@
         return frameLatch.await(timeout, TimeUnit.MILLISECONDS);
     }
 
+    @SmallTest
     @Test
     public void testSingleFrameAnimation() throws Throwable {
         int resId = R.drawable.avd_single_frame;
@@ -208,6 +211,7 @@
         });
     }
 
+    @MediumTest
     @Test
     public void testEmptyAnimatorSet() throws Throwable {
         int resId = R.drawable.avd_empty_animator;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
index 65aad83..d1f6282 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
@@ -36,7 +36,8 @@
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.AttributeSet;
@@ -50,7 +51,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class AnimatedVectorDrawableTest {
     private static final int IMAGE_WIDTH = 64;
@@ -75,6 +76,7 @@
         mResources = mActivity.getResources();
     }
 
+    @SmallTest
     @Test
     public void testInflate() throws Exception {
         // Setup AnimatedVectorDrawable from xml file
@@ -144,6 +146,7 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
+    @SmallTest
     @Test
     public void testMutate() {
         AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
@@ -178,6 +181,7 @@
         }
     }
 
+    @SmallTest
     @Test
     public void testGetOpacity() {
         AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
@@ -186,6 +190,7 @@
         assertEquals("Still translucent", PixelFormat.TRANSLUCENT, d1.getOpacity());
     }
 
+    @SmallTest
     @Test
     public void testColorFilter() {
         PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java
index 136ae2d..abba96e 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/CustomAnimationScaleListDrawableTest.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.DrawableContainer;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.After;
@@ -39,7 +40,7 @@
  * on animation duration scale. When the scale is 0, it is a static drawable, otherwise, it is an
  * animatable drawable.
  */
-@MediumTest
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class CustomAnimationScaleListDrawableTest {
     private static final int DRAWABLE_ID = R.drawable.custom_animation_scale_list_drawable;
@@ -58,7 +59,6 @@
         ValueAnimator.setDurationScale(mOriginalScale);
     }
 
-    @MediumTest
     @Test
     public void testNonZeroDurationScale() {
         // Set the duration scale to a non-zero value will cause the AnimationScaleListDrawable's
@@ -69,7 +69,6 @@
         assertTrue(dr.getCurrent() instanceof Animatable);
     }
 
-    @MediumTest
     @Test
     public void testZeroDurationScale() {
         // Set the duration scale to zero will cause the AnimationScaleListDrawable's current
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java
index 4849e71..c8d057a 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DefaultFocusHighlightTest.java
@@ -46,14 +46,15 @@
 import android.graphics.drawable.shapes.RectShape;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.StateSet;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@MediumTest
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DefaultFocusHighlightTest {
 
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
index 05360d8..b798fb8 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
@@ -52,6 +52,7 @@
 import java.io.IOException;
 import java.util.Arrays;
 
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class GradientDrawableTest {
     private Resources mResources;
@@ -61,7 +62,6 @@
         mResources = InstrumentationRegistry.getTargetContext().getResources();
     }
 
-    @SmallTest
     @Test
     public void testConstructor() {
         int[] color = new int[] {1, 2, 3};
@@ -71,7 +71,6 @@
         new GradientDrawable(null, null);
     }
 
-    @SmallTest
     @Test
     public void testGetOpacity() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -105,7 +104,6 @@
 
     }
 
-    @SmallTest
     @Test
     public void testSetOrientation() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -117,7 +115,6 @@
                 orientation, gradientDrawable.getOrientation());
     }
 
-    @SmallTest
     @Test
     public void testSetCornerRadii() {
         float[] radii = new float[] {1.0f, 2.0f, 3.0f};
@@ -136,7 +133,6 @@
         gradientDrawable.setCornerRadii(null);
     }
 
-    @SmallTest
     @Test
     public void testSetCornerRadius() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -145,7 +141,6 @@
         gradientDrawable.setCornerRadius(-2.5f);
     }
 
-    @SmallTest
     @Test
     public void testGetCornerRadius() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -160,7 +155,6 @@
         assertEquals(0, gradientDrawable.getCornerRadius(), 0);
     }
 
-    @SmallTest
     @Test
     public void testSetStroke() {
         helpTestSetStroke(2, Color.RED);
@@ -174,7 +168,6 @@
         // TODO: Verify stroke properties.
     }
 
-    @SmallTest
     @Test
     public void testSetStroke_WidthGap() {
         verifySetStroke_WidthGap(2, Color.RED, 3.4f, 5.5f);
@@ -189,7 +182,6 @@
         // TODO: Verify stroke properties.
     }
 
-    @SmallTest
     @Test
     public void testSetStrokeList() {
         verifySetStrokeList(2, ColorStateList.valueOf(Color.RED));
@@ -204,7 +196,6 @@
         // TODO: Verify stroke properties.
     }
 
-    @SmallTest
     @Test
     public void testSetStrokeList_WidthGap() {
         verifySetStrokeList_WidthGap(2, ColorStateList.valueOf(Color.RED), 3.4f, 5.5f);
@@ -219,7 +210,6 @@
         // TODO: Verify stroke properties.
     }
 
-    @SmallTest
     @Test
     public void testSetSize() {
         verifySetSize(6, 4);
@@ -235,7 +225,6 @@
         assertEquals(height, gradientDrawable.getIntrinsicHeight());
     }
 
-    @SmallTest
     @Test
     public void testSetShape() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -252,7 +241,6 @@
                 shape, gradientDrawable.getShape());
     }
 
-    @SmallTest
     @Test
     public void testSetGradientType() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -269,7 +257,6 @@
                 gradientType, gradientDrawable.getGradientType());
     }
 
-    @SmallTest
     @Test
     public void testSetGradientCenter() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -294,7 +281,6 @@
         assertEquals(centerY, gradientDrawable.getGradientCenterY(), 0.01f);
     }
 
-    @SmallTest
     @Test
     public void testSetGradientRadius() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -303,7 +289,6 @@
         gradientDrawable.setGradientRadius(-3.6f);
     }
 
-    @SmallTest
     @Test
     public void testSetUseLevel() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -322,7 +307,6 @@
                 useLevel, gradientDrawable.getUseLevel());
     }
 
-    @SmallTest
     @Test
     public void testDraw() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -333,7 +317,6 @@
         gradientDrawable.draw(null);
     }
 
-    @SmallTest
     @Test
     public void testSetColor() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -350,7 +333,6 @@
                 gradientDrawable.getColor().getDefaultColor());
     }
 
-    @SmallTest
     @Test
     public void testSetColors() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -367,7 +349,6 @@
                 colors, gradientDrawable.getColors());
     }
 
-    @SmallTest
     @Test
     public void testSetColorList() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -382,7 +363,6 @@
         assertEquals("Color was set to null (TRANSPARENT)", color, gradientDrawable.getColor());
     }
 
-    @SmallTest
     @Test
     public void testGetChangingConfigurations() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -395,7 +375,6 @@
         assertEquals(-20, gradientDrawable.getChangingConfigurations());
     }
 
-    @SmallTest
     @Test
     public void testSetAlpha() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -404,7 +383,6 @@
         gradientDrawable.setAlpha(-1);
     }
 
-    @SmallTest
     @Test
     public void testSetDither() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -413,7 +391,6 @@
         gradientDrawable.setDither(false);
     }
 
-    @SmallTest
     @Test
     public void testSetColorFilter() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -424,7 +401,6 @@
         gradientDrawable.setColorFilter(null);
     }
 
-    @SmallTest
     @Test
     public void testInflate() throws XmlPullParserException, IOException {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -469,7 +445,6 @@
         }
     }
 
-    @SmallTest
     @Test
     public void testInflateGradientRadius() throws XmlPullParserException, IOException {
         Rect parentBounds = new Rect(0, 0, 100, 100);
@@ -490,7 +465,6 @@
         assertEquals(50.0f, radius, 0.0f);
     }
 
-    @SmallTest
     @Test
     public void testGetIntrinsicWidth() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -501,7 +475,6 @@
         assertEquals(-10, gradientDrawable.getIntrinsicWidth());
     }
 
-    @SmallTest
     @Test
     public void testGetIntrinsicHeight() {
         GradientDrawable gradientDrawable = new GradientDrawable();
@@ -512,14 +485,12 @@
         assertEquals(-15, gradientDrawable.getIntrinsicHeight());
     }
 
-    @SmallTest
     @Test
     public void testGetConstantState() {
         GradientDrawable gradientDrawable = new GradientDrawable();
         assertNotNull(gradientDrawable.getConstantState());
     }
 
-    @SmallTest
     @Test
     public void testMutate() {
         GradientDrawable d1 =
@@ -555,7 +526,6 @@
         assertEquals(40, d3.getIntrinsicWidth());
     }
 
-    @MediumTest
     @Test
     public void testPreloadDensity() throws XmlPullParserException, IOException {
         final int densityDpi = mResources.getConfiguration().densityDpi;
@@ -567,7 +537,6 @@
         }
     }
 
-    @MediumTest
     @Test
     public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
         final int densityDpi = mResources.getConfiguration().densityDpi;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index bc2aecb..276bf50 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -33,7 +33,6 @@
 import android.graphics.drawable.Drawable.ConstantState;
 import android.graphics.drawable.VectorDrawable;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.AttributeSet;
@@ -50,6 +49,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class VectorDrawableTest {
     private static final String LOGTAG = "VectorDrawableTest";
@@ -200,31 +200,26 @@
         mResources = InstrumentationRegistry.getTargetContext().getResources();
     }
 
-    @MediumTest
     @Test
     public void testBasicVectorDrawables() throws XmlPullParserException, IOException {
         verifyVectorDrawables(BASIC_ICON_RES_IDS, BASIC_GOLDEN_IMAGES, null);
     }
 
-    @MediumTest
     @Test
     public void testLMVectorDrawables() throws XmlPullParserException, IOException {
         verifyVectorDrawables(L_M_ICON_RES_IDS, L_M_GOLDEN_IMAGES, null);
     }
 
-    @MediumTest
     @Test
     public void testNVectorDrawables() throws XmlPullParserException, IOException {
         verifyVectorDrawables(N_ICON_RES_IDS, N_GOLDEN_IMAGES, null);
     }
 
-    @MediumTest
     @Test
     public void testVectorDrawableGradient() throws XmlPullParserException, IOException {
         verifyVectorDrawables(GRADIENT_ICON_RES_IDS, GRADIENT_GOLDEN_IMAGES, null);
     }
 
-    @MediumTest
     @Test
     public void testColorStateList() throws XmlPullParserException, IOException {
         for (int i = 0; i < STATEFUL_STATE_SETS.length; i++) {
@@ -344,7 +339,6 @@
         return builder.toString();
     }
 
-    @SmallTest
     @Test
     public void testGetChangingConfigurations() {
         VectorDrawable vectorDrawable = new VectorDrawable();
@@ -369,7 +363,6 @@
         assertEquals(0xffff,  vectorDrawable.getChangingConfigurations());
     }
 
-    @SmallTest
     @Test
     public void testGetConstantState() {
         VectorDrawable vectorDrawable = new VectorDrawable();
@@ -383,7 +376,6 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
-    @SmallTest
     @Test
     public void testMutate() {
         // d1 and d2 will be mutated, while d3 will not.
@@ -419,7 +411,6 @@
         }
     }
 
-    @SmallTest
     @Test
     public void testColorFilter() {
         PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, Mode.SRC_IN);
@@ -429,7 +420,6 @@
         assertEquals(filter, vectorDrawable.getColorFilter());
     }
 
-    @SmallTest
     @Test
     public void testGetOpacity () throws XmlPullParserException, IOException {
         VectorDrawable vectorDrawable = new VectorDrawable();
@@ -444,7 +434,6 @@
                 vectorDrawable.getOpacity());
     }
 
-    @SmallTest
     @Test
     public void testPreloadDensity() throws XmlPullParserException, IOException {
         final int densityDpi = mResources.getConfiguration().densityDpi;
@@ -456,7 +445,6 @@
         }
     }
 
-    @SmallTest
     @Test
     public void testPreloadDensity_tvdpi() throws XmlPullParserException, IOException {
         final int densityDpi = mResources.getConfiguration().densityDpi;
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
index 0cbbe7e..99c0ac1 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
@@ -36,13 +36,63 @@
             "android.media.cts", "android.media.cts.StubMediaBrowserService");
     private final Object mWaitLock = new Object();
 
-    private final ConnectionCallback mConnectionCallback = new ConnectionCallback();
-    private final SubscriptionCallback mSubscriptionCallback = new SubscriptionCallback();
-    private final ItemCallback mItemCallback = new ItemCallback();
-    private final SearchCallback mSearchCallback = new SearchCallback();
+    private final MediaBrowser.ConnectionCallback mConnectionCallback =
+            new MediaBrowser.ConnectionCallback() {
+        @Override
+        public void onConnected() {
+            synchronized (mWaitLock) {
+                mMediaBrowserService = StubMediaBrowserService.sInstance;
+                mWaitLock.notify();
+            }
+        }
+    };
+
+    private final MediaBrowser.SubscriptionCallback mSubscriptionCallback =
+            new MediaBrowser.SubscriptionCallback() {
+            @Override
+            public void onChildrenLoaded(String parentId, List<MediaItem> children) {
+                synchronized (mWaitLock) {
+                    mOnChildrenLoaded = true;
+                    if (children != null) {
+                        for (MediaItem item : children) {
+                            assertRootHints(item);
+                        }
+                    }
+                    mWaitLock.notify();
+                }
+            }
+
+            @Override
+            public void onChildrenLoaded(String parentId, List<MediaItem> children,
+                    Bundle options) {
+                synchronized (mWaitLock) {
+                    mOnChildrenLoadedWithOptions = true;
+                    if (children != null) {
+                        for (MediaItem item : children) {
+                            assertRootHints(item);
+                        }
+                    }
+                    mWaitLock.notify();
+                }
+            }
+        };
+
+    private final MediaBrowser.ItemCallback mItemCallback = new MediaBrowser.ItemCallback() {
+        @Override
+        public void onItemLoaded(MediaItem item) {
+            synchronized (mWaitLock) {
+                mOnItemLoaded = true;
+                assertRootHints(item);
+                mWaitLock.notify();
+            }
+        }
+    };
 
     private MediaBrowser mMediaBrowser;
     private StubMediaBrowserService mMediaBrowserService;
+    private boolean mOnChildrenLoaded;
+    private boolean mOnChildrenLoadedWithOptions;
+    private boolean mOnItemLoaded;
     private Bundle mRootHints;
 
     @Override
@@ -72,15 +122,14 @@
 
     public void testNotifyChildrenChanged() throws Exception {
         synchronized (mWaitLock) {
-            mSubscriptionCallback.reset();
             mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_ROOT, mSubscriptionCallback);
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoaded);
+            assertTrue(mOnChildrenLoaded);
 
-            mSubscriptionCallback.reset();
+            mOnChildrenLoaded = false;
             mMediaBrowserService.notifyChildrenChanged(StubMediaBrowserService.MEDIA_ID_ROOT);
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoaded);
+            assertTrue(mOnChildrenLoaded);
         }
     }
 
@@ -92,54 +141,53 @@
             options.putInt(MediaBrowser.EXTRA_PAGE_SIZE, pageSize);
             options.putInt(MediaBrowser.EXTRA_PAGE, page);
 
-            mSubscriptionCallback.reset();
             mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_ROOT, options,
                     mSubscriptionCallback);
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoadedWithOptions);
+            assertTrue(mOnChildrenLoadedWithOptions);
 
-            mSubscriptionCallback.reset();
+            mOnChildrenLoadedWithOptions = false;
             mMediaBrowserService.notifyChildrenChanged(StubMediaBrowserService.MEDIA_ID_ROOT);
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoadedWithOptions);
+            assertTrue(mOnChildrenLoadedWithOptions);
         }
     }
 
     public void testDelayedNotifyChildrenChanged() throws Exception {
         synchronized (mWaitLock) {
-            mSubscriptionCallback.reset();
+            mOnChildrenLoaded = false;
             mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED,
                     mSubscriptionCallback);
             mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertFalse(mSubscriptionCallback.mOnChildrenLoaded);
+            assertFalse(mOnChildrenLoaded);
 
             mMediaBrowserService.sendDelayedNotifyChildrenChanged();
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoaded);
+            assertTrue(mOnChildrenLoaded);
 
-            mSubscriptionCallback.reset();
+            mOnChildrenLoaded = false;
             mMediaBrowserService.notifyChildrenChanged(
                     StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED);
             mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertFalse(mSubscriptionCallback.mOnChildrenLoaded);
+            assertFalse(mOnChildrenLoaded);
 
             mMediaBrowserService.sendDelayedNotifyChildrenChanged();
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mSubscriptionCallback.mOnChildrenLoaded);
+            assertTrue(mOnChildrenLoaded);
         }
     }
 
     public void testDelayedItem() throws Exception {
         synchronized (mWaitLock) {
-            mItemCallback.reset();
-            mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED, mItemCallback);
+            mOnItemLoaded = false;
+            mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED,
+                    mItemCallback);
             mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertFalse(mItemCallback.mOnItemLoaded);
+            assertFalse(mOnItemLoaded);
 
-            mItemCallback.reset();
             mMediaBrowserService.sendDelayedItemLoaded();
             mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mItemCallback.mOnItemLoaded);
+            assertTrue(mOnItemLoaded);
         }
     }
 
@@ -155,60 +203,6 @@
         assertEquals(val, browserRoot.getExtras().getString(key));
     }
 
-    public void testSearch() throws Exception {
-        final String key = "test-key";
-        final String val = "test-val";
-
-        final MediaBrowser.SearchCallback searchCallback =
-                (MediaBrowser.SearchCallback) mSearchCallback;
-        final MediaBrowserService mediaBrowserService = (MediaBrowserService) mMediaBrowserService;
-
-        synchronized (mWaitLock) {
-            mSearchCallback.reset();
-            mMediaBrowser.search(StubMediaBrowserService.SEARCH_QUERY_FOR_NO_RESULT, null,
-                    mSearchCallback);
-            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertTrue(mSearchCallback.mOnSearchResult);
-            assertTrue(mSearchCallback.mSearchResults != null
-                    && mSearchCallback.mSearchResults.size() == 0);
-            assertEquals(null, mSearchCallback.mSearchExtras);
-            // just call the callback once directly so it's marked as tested
-            mediaBrowserService.onSearch(
-                    StubMediaBrowserService.SEARCH_QUERY_FOR_NO_RESULT, null, null);
-            searchCallback.onSearchResult(StubMediaBrowserService.SEARCH_QUERY_FOR_NO_RESULT,
-                    mSearchCallback.mSearchExtras, mSearchCallback.mSearchResults);
-
-            mSearchCallback.reset();
-            mMediaBrowser.search(StubMediaBrowserService.SEARCH_QUERY_FOR_ERROR, null,
-                    mSearchCallback);
-            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertTrue(mSearchCallback.mOnSearchResult);
-            assertNull(mSearchCallback.mSearchResults);
-            assertEquals(null, mSearchCallback.mSearchExtras);
-            // just call the callback once directly so it's marked as tested
-            mediaBrowserService.onSearch(
-                    StubMediaBrowserService.SEARCH_QUERY_FOR_ERROR, null, null);
-            searchCallback.onError(StubMediaBrowserService.SEARCH_QUERY_FOR_ERROR, null);
-
-            mSearchCallback.reset();
-            Bundle extras = new Bundle();
-            extras.putString(key, val);
-            mMediaBrowser.search(StubMediaBrowserService.SEARCH_QUERY, extras, mSearchCallback);
-            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
-            assertTrue(mSearchCallback.mOnSearchResult);
-            assertNotNull(mSearchCallback.mSearchResults);
-            for (MediaItem item : mSearchCallback.mSearchResults) {
-                assertTrue(item.getMediaId().contains(StubMediaBrowserService.SEARCH_QUERY));
-            }
-            assertNotNull(mSearchCallback.mSearchExtras);
-            assertEquals(val, mSearchCallback.mSearchExtras.getString(key));
-            // just call the callback once directly so it's marked as tested
-            mediaBrowserService.onSearch(StubMediaBrowserService.SEARCH_QUERY, extras, null);
-            searchCallback.onSearchResult(StubMediaBrowserService.SEARCH_QUERY,
-                    mSearchCallback.mSearchExtras, mSearchCallback.mSearchResults);
-        }
-    }
-
     private void assertRootHints(MediaItem item) {
         Bundle rootHints = item.getDescription().getExtras();
         assertNotNull(rootHints);
@@ -219,100 +213,4 @@
         assertEquals(mRootHints.getBoolean(BrowserRoot.EXTRA_SUGGESTED),
                 rootHints.getBoolean(BrowserRoot.EXTRA_SUGGESTED));
     }
-
-    private class ConnectionCallback extends MediaBrowser.ConnectionCallback {
-        @Override
-        public void onConnected() {
-            synchronized (mWaitLock) {
-                mMediaBrowserService = StubMediaBrowserService.sInstance;
-                mWaitLock.notify();
-            }
-        }
-    }
-
-    private class SubscriptionCallback extends MediaBrowser.SubscriptionCallback {
-        boolean mOnChildrenLoaded;
-        boolean mOnChildrenLoadedWithOptions;
-
-        @Override
-        public void onChildrenLoaded(String parentId, List<MediaItem> children) {
-            synchronized (mWaitLock) {
-                mOnChildrenLoaded = true;
-                if (children != null) {
-                    for (MediaItem item : children) {
-                        assertRootHints(item);
-                    }
-                }
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onChildrenLoaded(String parentId, List<MediaItem> children,
-                Bundle options) {
-            synchronized (mWaitLock) {
-                mOnChildrenLoadedWithOptions = true;
-                if (children != null) {
-                    for (MediaItem item : children) {
-                        assertRootHints(item);
-                    }
-                }
-                mWaitLock.notify();
-            }
-        }
-
-        public void reset() {
-            mOnChildrenLoaded = false;
-            mOnChildrenLoadedWithOptions = false;
-        }
-    }
-
-    private class ItemCallback extends MediaBrowser.ItemCallback {
-        boolean mOnItemLoaded;
-
-        @Override
-        public void onItemLoaded(MediaItem item) {
-            synchronized (mWaitLock) {
-                mOnItemLoaded = true;
-                assertRootHints(item);
-                mWaitLock.notify();
-            }
-        }
-
-        public void reset() {
-            mOnItemLoaded = false;
-        }
-    }
-
-    private class SearchCallback extends MediaBrowser.SearchCallback {
-        boolean mOnSearchResult;
-        Bundle mSearchExtras;
-        List<MediaItem> mSearchResults;
-
-        @Override
-        public void onSearchResult(String query, Bundle extras, List<MediaItem> items) {
-            synchronized (mWaitLock) {
-                mOnSearchResult = true;
-                mSearchResults = items;
-                mSearchExtras = extras;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onError(String query, Bundle extras) {
-            synchronized (mWaitLock) {
-                mOnSearchResult = true;
-                mSearchResults = null;
-                mSearchExtras = extras;
-                mWaitLock.notify();
-            }
-        }
-
-        public void reset() {
-            mOnSearchResult = false;
-            mSearchExtras = null;
-            mSearchResults = null;
-        }
-    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaControllerTest.java b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
index 9aaf1aa..17588ee 100644
--- a/tests/tests/media/src/android/media/cts/MediaControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
@@ -19,11 +19,8 @@
 import android.media.AudioManager;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.MediaDescription;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
-import android.media.session.MediaSession.QueueItem;
-import android.media.session.PlaybackState;
 import android.media.session.PlaybackState.CustomAction;
 import android.net.Uri;
 import android.os.Bundle;
@@ -53,7 +50,6 @@
         super.setUp();
         mSession = new MediaSession(getContext(), SESSION_TAG);
         mSession.setCallback(mCallback, mHandler);
-        mSession.setFlags(MediaSession.FLAG_HANDLES_QUEUE_COMMANDS);
         mController = mSession.getController();
     }
 
@@ -88,53 +84,6 @@
         }
     }
 
-    public void testAddRemoveQueueItems() throws Exception {
-        final String mediaId = "media_id";
-        final String mediaTitle = "media_title";
-        MediaDescription itemDescription = new MediaDescription.Builder()
-                .setMediaId(mediaId).setTitle(mediaTitle).build();
-        final MediaSession.Callback callback = (MediaSession.Callback) mCallback;
-
-        synchronized (mWaitLock) {
-            mCallback.reset();
-            mController.addQueueItem(itemDescription);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnAddQueueItemCalled);
-            assertEquals(-1, mCallback.mQueueIndex);
-            assertEquals(mediaId, mCallback.mQueueDescription.getMediaId());
-            assertEquals(mediaTitle, mCallback.mQueueDescription.getTitle());
-            // just call the callback once directly so it's marked as tested
-            callback.onAddQueueItem(mCallback.mQueueDescription);
-
-            mCallback.reset();
-            mController.addQueueItem(itemDescription, 0);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnAddQueueItemAtCalled);
-            assertEquals(0, mCallback.mQueueIndex);
-            assertEquals(mediaId, mCallback.mQueueDescription.getMediaId());
-            assertEquals(mediaTitle, mCallback.mQueueDescription.getTitle());
-            // just call the callback once directly so it's marked as tested
-            callback.onAddQueueItem(mCallback.mQueueDescription, mCallback.mQueueIndex);
-
-            mCallback.reset();
-            mController.removeQueueItemAt(0);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnRemoveQueueItemAtCalled);
-            assertEquals(0, mCallback.mQueueIndex);
-            // just call the callback once directly so it's marked as tested
-            callback.onRemoveQueueItemAt(mCallback.mQueueIndex);
-
-            mCallback.reset();
-            mController.removeQueueItem(itemDescription);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnRemoveQueueItemCalled);
-            assertEquals(mediaId, mCallback.mQueueDescription.getMediaId());
-            assertEquals(mediaTitle, mCallback.mQueueDescription.getTitle());
-            // just call the callback once directly so it's marked as tested
-            callback.onRemoveQueueItem(mCallback.mQueueDescription);
-        }
-    }
-
     public void testVolumeControl() throws Exception {
         VolumeProvider vp = new VolumeProvider(VolumeProvider.VOLUME_CONTROL_ABSOLUTE, 11, 5) {
             @Override
@@ -346,26 +295,6 @@
             assertTrue(mCallback.mOnPrepareFromUriCalled);
             assertEquals(uri, mCallback.mUri);
             assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
-            // just call the callback once directly so it's marked as tested
-            callback.onPrepareFromUri(mCallback.mUri, mCallback.mExtras);
-
-            mCallback.reset();
-            final int repeatMode = PlaybackState.REPEAT_MODE_ALL;
-            controls.setRepeatMode(repeatMode);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnSetRepeatModeCalled);
-            assertEquals(repeatMode, mCallback.mRepeatMode);
-            // just call the callback once directly so it's marked as tested
-            callback.onSetRepeatMode(mCallback.mRepeatMode);
-
-            mCallback.reset();
-            final boolean shuffleModeEnabled = true;
-            controls.setShuffleModeEnabled(shuffleModeEnabled);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnSetShuffleModeEnabledCalled);
-            assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
-            // just call the callback once directly so it's marked as tested
-            callback.onSetShuffleModeEnabled(mCallback.mShuffleModeEnabled);
         }
     }
 
@@ -389,8 +318,6 @@
     private class MediaSessionCallback extends MediaSession.Callback {
         private long mSeekPosition;
         private long mQueueItemId;
-        private int mQueueIndex;
-        private MediaDescription mQueueDescription;
         private Rating mRating;
         private String mMediaId;
         private String mQuery;
@@ -399,8 +326,6 @@
         private String mCommand;
         private Bundle mExtras;
         private ResultReceiver mCommandCallback;
-        private int mRepeatMode;
-        private boolean mShuffleModeEnabled;
 
         private boolean mOnPlayCalled;
         private boolean mOnPauseCalled;
@@ -421,18 +346,10 @@
         private boolean mOnPrepareFromMediaIdCalled;
         private boolean mOnPrepareFromSearchCalled;
         private boolean mOnPrepareFromUriCalled;
-        private boolean mOnSetRepeatModeCalled;
-        private boolean mOnSetShuffleModeEnabledCalled;
-        private boolean mOnAddQueueItemCalled;
-        private boolean mOnAddQueueItemAtCalled;
-        private boolean mOnRemoveQueueItemCalled;
-        private boolean mOnRemoveQueueItemAtCalled;
 
         public void reset() {
             mSeekPosition = -1;
             mQueueItemId = -1;
-            mQueueIndex = -1;
-            mQueueDescription = null;
             mRating = null;
             mMediaId = null;
             mQuery = null;
@@ -441,8 +358,6 @@
             mExtras = null;
             mCommand = null;
             mCommandCallback = null;
-            mShuffleModeEnabled = false;
-            mRepeatMode = PlaybackState.REPEAT_MODE_NONE;
 
             mOnPlayCalled = false;
             mOnPauseCalled = false;
@@ -463,12 +378,6 @@
             mOnPrepareFromMediaIdCalled = false;
             mOnPrepareFromSearchCalled = false;
             mOnPrepareFromUriCalled = false;
-            mOnSetRepeatModeCalled = false;
-            mOnSetShuffleModeEnabledCalled = false;
-            mOnAddQueueItemCalled = false;
-            mOnAddQueueItemAtCalled = false;
-            mOnRemoveQueueItemCalled = false;
-            mOnRemoveQueueItemAtCalled = false;
         }
 
         @Override
@@ -642,60 +551,5 @@
                 mWaitLock.notify();
             }
         }
-
-        @Override
-        public void onSetRepeatMode(int repeatMode) {
-            synchronized (mWaitLock) {
-                mOnSetRepeatModeCalled = true;
-                mRepeatMode = repeatMode;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onSetShuffleModeEnabled(boolean enabled) {
-            synchronized (mWaitLock) {
-                mOnSetShuffleModeEnabledCalled = true;
-                mShuffleModeEnabled = enabled;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onAddQueueItem(MediaDescription description) {
-            synchronized (mWaitLock) {
-                mOnAddQueueItemCalled = true;
-                mQueueDescription = description;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onAddQueueItem(MediaDescription description, int index) {
-            synchronized (mWaitLock) {
-                mOnAddQueueItemAtCalled = true;
-                mQueueIndex = index;
-                mQueueDescription = description;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onRemoveQueueItem(MediaDescription description) {
-            synchronized (mWaitLock) {
-                mOnRemoveQueueItemCalled = true;
-                mQueueDescription = description;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onRemoveQueueItemAt(int index) {
-            synchronized (mWaitLock) {
-                mOnRemoveQueueItemAtCalled = true;
-                mQueueIndex = index;
-                mWaitLock.notify();
-            }
-        }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index bc07ba6..d3c392c 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -520,6 +520,19 @@
         fos.close();
     }
 
+    public void testSetOutputFile() throws Exception {
+        if (!hasCamera()) {
+            return;
+        }
+        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
+        mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
+        mMediaRecorder.setOutputFile(mOutFile);
+        long maxFileSize = MAX_FILE_SIZE * 10;
+        recordMedia(maxFileSize, mOutFile);
+    }
+
     public void testRecordingAudioInRawFormats() throws Exception {
         int testsRun = 0;
         if (hasAmrNb()) {
@@ -771,7 +784,8 @@
                     } else if (mFileIndex < 6) {
                         try {
                             String path = OUTPUT_PATH + mFileIndex;
-                            mMediaRecorder.setNextOutputFile(path);
+                            File nextFile = new File(path);
+                            mMediaRecorder.setNextOutputFile(nextFile);
                             recordFileList.add(path);
                             mFileIndex++;
                         } catch (IOException e) {
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index 50b3033..07f63da 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -149,6 +149,9 @@
         session.setPlaybackState(state);
         session.setActive(true);
 
+        // A media playback is also needed to receive media key events.
+        Utils.assertMediaPlaybackStarted(getInstrumentation().getTargetContext());
+
         // Ensure that the listener is called for media key event,
         // and any other media sessions don't get the key.
         MediaKeyListener listener = new MediaKeyListener(2, true, handler);
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index b84bf1c..5f13a2e 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -222,28 +222,6 @@
             mSession.setSessionActivity(pi);
             assertEquals(pi, controller.getSessionActivity());
 
-            // test setRepeatMode
-            mCallback.resetLocked();
-            final int repeatMode = PlaybackState.REPEAT_MODE_ALL;
-            mSession.setRepeatMode(repeatMode);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnRepeatModeChangedCalled);
-            assertEquals(repeatMode, mCallback.mRepeatMode);
-            assertEquals(repeatMode, controller.getRepeatMode());
-            // just call the callback once directly so it's marked as tested
-            callback.onRepeatModeChanged(mCallback.mRepeatMode);
-
-            // test setShuffleModeEnabled
-            mCallback.resetLocked();
-            final boolean shuffleModeEnabled = true;
-            mSession.setShuffleModeEnabled(shuffleModeEnabled);
-            mWaitLock.wait(TIME_OUT_MS);
-            assertTrue(mCallback.mOnShuffleModeChangedCalled);
-            assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
-            assertEquals(shuffleModeEnabled, controller.isShuffleModeEnabled());
-            // just call the callback once directly so it's marked as tested
-            callback.onShuffleModeChanged(mCallback.mShuffleModeEnabled);
-
             // test setActivity
             mSession.setActive(true);
             assertTrue(mSession.isActive());
@@ -354,6 +332,9 @@
                 .setState(PlaybackState.STATE_PLAYING, 0L, 0.0f).build();
         mSession.setPlaybackState(defaultState);
 
+        // A media playback is also needed to receive media key events.
+        Utils.assertMediaPlaybackStarted(getContext());
+
         synchronized (mWaitLock) {
             sessionCallback.reset();
             simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY);
@@ -474,8 +455,6 @@
         private volatile boolean mOnAudioInfoChangedCalled;
         private volatile boolean mOnSessionDestroyedCalled;
         private volatile boolean mOnSessionEventCalled;
-        private volatile boolean mOnRepeatModeChangedCalled;
-        private volatile boolean mOnShuffleModeChangedCalled;
 
         private volatile PlaybackState mPlaybackState;
         private volatile MediaMetadata mMediaMetadata;
@@ -484,8 +463,6 @@
         private volatile String mEvent;
         private volatile Bundle mExtras;
         private volatile MediaController.PlaybackInfo mPlaybackInfo;
-        private volatile int mRepeatMode;
-        private volatile boolean mShuffleModeEnabled;
 
         public void resetLocked() {
             mOnPlaybackStateChangedCalled = false;
@@ -496,8 +473,6 @@
             mOnAudioInfoChangedCalled = false;
             mOnSessionDestroyedCalled = false;
             mOnSessionEventCalled = false;
-            mOnRepeatModeChangedCalled = false;
-            mOnShuffleModeChangedCalled = false;
 
             mPlaybackState = null;
             mMediaMetadata = null;
@@ -505,8 +480,6 @@
             mTitle = null;
             mExtras = null;
             mPlaybackInfo = null;
-            mRepeatMode = PlaybackState.REPEAT_MODE_NONE;
-            mShuffleModeEnabled = false;
         }
 
         @Override
@@ -580,24 +553,6 @@
                 mWaitLock.notify();
             }
         }
-
-        @Override
-        public void onRepeatModeChanged(int repeatMode) {
-            synchronized (mWaitLock) {
-                mOnRepeatModeChangedCalled = true;
-                mRepeatMode = repeatMode;
-                mWaitLock.notify();
-            }
-        }
-
-        @Override
-        public void onShuffleModeChanged(boolean enabled) {
-            synchronized (mWaitLock) {
-                mOnShuffleModeChangedCalled = true;
-                mShuffleModeEnabled = enabled;
-                mWaitLock.notify();
-            }
-        }
     }
 
     private class MediaSessionCallback extends MediaSession.Callback {
diff --git a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
index 888b3d4..9f90a75 100644
--- a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
@@ -45,10 +45,6 @@
         MEDIA_ID_CHILDREN_DELAYED
     };
 
-    static final String SEARCH_QUERY = "test_media_children";
-    static final String SEARCH_QUERY_FOR_NO_RESULT = "query no result";
-    static final String SEARCH_QUERY_FOR_ERROR = "query for error";
-
     static StubMediaBrowserService sInstance;
 
     /* package private */ static MediaSession sSession;
@@ -76,8 +72,10 @@
     public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) {
         List<MediaItem> mediaItems = new ArrayList<>();
         if (MEDIA_ID_ROOT.equals(parentMediaId)) {
+            Bundle rootHints = getBrowserRootHints();
             for (String id : MEDIA_ID_CHILDREN) {
-                mediaItems.add(createMediaItem(id));
+                mediaItems.add(new MediaItem(new MediaDescription.Builder()
+                        .setMediaId(id).setExtras(rootHints).build(), MediaItem.FLAG_BROWSABLE));
             }
             result.sendResult(mediaItems);
         } else if (MEDIA_ID_CHILDREN_DELAYED.equals(parentMediaId)) {
@@ -101,7 +99,9 @@
 
         for (String id : MEDIA_ID_CHILDREN) {
             if (id.equals(itemId)) {
-                result.sendResult(createMediaItem(id));
+                result.sendResult(new MediaItem(new MediaDescription.Builder()
+                        .setMediaId(id).setExtras(getBrowserRootHints()).build(),
+                                MediaItem.FLAG_BROWSABLE));
                 return;
             }
         }
@@ -109,27 +109,6 @@
         super.onLoadItem(itemId, result);
     }
 
-    @Override
-    public void onSearch(String query, Bundle extras, Result<List<MediaItem>> result) {
-        if (result == null) {
-            // called the callback to mark as tested
-            return;
-        }
-        if (SEARCH_QUERY_FOR_NO_RESULT.equals(query)) {
-            result.sendResult(Collections.<MediaItem>emptyList());
-        } else if (SEARCH_QUERY_FOR_ERROR.equals(query)) {
-            result.sendResult(null);
-        } else if (SEARCH_QUERY.equals(query)) {
-            List<MediaItem> items = new ArrayList<>();
-            for (String id : MEDIA_ID_CHILDREN) {
-                if (id.contains(query)) {
-                    items.add(createMediaItem(id));
-                }
-            }
-            result.sendResult(items);
-        }
-    }
-
     public void sendDelayedNotifyChildrenChanged() {
         if (mPendingLoadChildrenResult != null) {
             mPendingLoadChildrenResult.sendResult(Collections.<MediaItem>emptyList());
@@ -147,10 +126,4 @@
             mPendingLoadItemResult = null;
         }
     }
-
-    private MediaItem createMediaItem(String id) {
-        return new MediaItem(new MediaDescription.Builder()
-                .setMediaId(id).setExtras(getBrowserRootHints()).build(),
-                MediaItem.FLAG_BROWSABLE);
-    }
 }
diff --git a/tests/tests/media/src/android/media/cts/Utils.java b/tests/tests/media/src/android/media/cts/Utils.java
index e8ceeae..fb461fe 100644
--- a/tests/tests/media/src/android/media/cts/Utils.java
+++ b/tests/tests/media/src/android/media/cts/Utils.java
@@ -20,15 +20,28 @@
 import android.app.UiAutomation;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.media.MediaPlayer;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.provider.Settings;
 
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 import java.util.Scanner;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
 
 public class Utils {
+    private static final String TAG = "CtsMediaTestUtil";
+    private static final int TEST_TIMING_TOLERANCE_MS = 50;
+
     public static void enableAppOps(String packageName, String operation,
             Instrumentation instrumentation) {
         setAppOps(packageName, operation, instrumentation, true);
@@ -113,4 +126,53 @@
         }
         uiAutomation.destroy();
     }
+
+    /**
+     * Assert that a media playback is started and an active {@link AudioPlaybackConfiguration}
+     * is created once. The playback will be stopped immediately after that.
+     * <p>For a media session to receive media button events, an actual playback is needed.
+     */
+    static void assertMediaPlaybackStarted(Context context) {
+        final AudioManager am = new AudioManager(context);
+        final HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        final TestAudioPlaybackCallback callback = new TestAudioPlaybackCallback();
+        MediaPlayer mediaPlayer = null;
+
+        try {
+            final int activeConfigSizeBeforeStart = am.getActivePlaybackConfigurations().size();
+            final Handler handler = new Handler(handlerThread.getLooper());
+
+            am.registerAudioPlaybackCallback(callback, handler);
+            mediaPlayer = MediaPlayer.create(context, R.raw.sine1khzs40dblong);
+            mediaPlayer.start();
+            if (!callback.mCountDownLatch.await(TEST_TIMING_TOLERANCE_MS, TimeUnit.MILLISECONDS)
+                    || callback.mActiveConfigSize != activeConfigSizeBeforeStart + 1) {
+                Assert.fail("Failed to create an active AudioPlaybackConfiguration");
+            }
+        } catch (InterruptedException e) {
+            Assert.fail("Failed to create an active AudioPlaybackConfiguration");
+        } finally {
+            am.unregisterAudioPlaybackCallback(callback);
+            if (mediaPlayer != null) {
+                mediaPlayer.stop();
+                mediaPlayer.release();
+                mediaPlayer = null;
+            }
+            handlerThread.quitSafely();
+        }
+    }
+
+    private static class TestAudioPlaybackCallback extends AudioManager.AudioPlaybackCallback {
+        private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
+        private int mActiveConfigSize;
+
+        @Override
+        public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+            // For non-framework apps, only anonymized active AudioPlaybackCallbacks will be
+            // notified.
+            mActiveConfigSize = configs.size();
+            mCountDownLatch.countDown();
+        }
+    }
 }
diff --git a/tests/tests/nativemedia/aaudio/Android.mk b/tests/tests/nativemedia/aaudio/Android.mk
index d8cfcf3..e37df49 100644
--- a/tests/tests/nativemedia/aaudio/Android.mk
+++ b/tests/tests/nativemedia/aaudio/Android.mk
@@ -28,6 +28,7 @@
 
 LOCAL_SRC_FILES := \
     src/test_aaudio.cpp \
+    src/test_aaudio_misc.cpp \
     src/test_aaudio_callback.cpp
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
index 4072fce..37b434e 100644
--- a/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio.cpp
@@ -146,7 +146,7 @@
 
     framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
     ASSERT_GE(framesPerBurst, 16);
-    ASSERT_LE(framesPerBurst, 4096); // TODO what is min/max?
+    ASSERT_LE(framesPerBurst, 10000); // TODO what is min/max?
 
     // Allocate a buffer for the audio data.
     // TODO handle possibility of other data formats
diff --git a/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp b/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp
new file mode 100644
index 0000000..a26f17a
--- /dev/null
+++ b/tests/tests/nativemedia/aaudio/src/test_aaudio_misc.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "AAudioTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <aaudio/AAudio.h>
+
+// Make sure enums do not change value.
+TEST(test_aaudio_misc, aaudio_freeze_enums) {
+
+    ASSERT_EQ(0, AAUDIO_DIRECTION_OUTPUT);
+    ASSERT_EQ(1, AAUDIO_DIRECTION_INPUT);
+
+    ASSERT_EQ(-1, AAUDIO_FORMAT_INVALID);
+    ASSERT_EQ(0, AAUDIO_FORMAT_UNSPECIFIED);
+    ASSERT_EQ(1, AAUDIO_FORMAT_PCM_I16);
+    ASSERT_EQ(2, AAUDIO_FORMAT_PCM_FLOAT);
+    ASSERT_EQ(3, AAUDIO_FORMAT_PCM_I8_24);
+    ASSERT_EQ(4, AAUDIO_FORMAT_PCM_I32);
+
+    ASSERT_EQ(0, AAUDIO_OK);
+    ASSERT_EQ(-900, AAUDIO_ERROR_BASE);
+    ASSERT_EQ(-899, AAUDIO_ERROR_DISCONNECTED);
+    ASSERT_EQ(-898, AAUDIO_ERROR_ILLEGAL_ARGUMENT);
+    ASSERT_EQ(-897, AAUDIO_ERROR_INCOMPATIBLE);
+    ASSERT_EQ(-896, AAUDIO_ERROR_INTERNAL);
+    ASSERT_EQ(-895, AAUDIO_ERROR_INVALID_STATE);
+    ASSERT_EQ(-894, AAUDIO_ERROR_UNEXPECTED_STATE);
+    ASSERT_EQ(-893, AAUDIO_ERROR_UNEXPECTED_VALUE);
+    ASSERT_EQ(-892, AAUDIO_ERROR_INVALID_HANDLE);
+    ASSERT_EQ(-891, AAUDIO_ERROR_INVALID_QUERY);
+    ASSERT_EQ(-890, AAUDIO_ERROR_UNIMPLEMENTED);
+    ASSERT_EQ(-889, AAUDIO_ERROR_UNAVAILABLE);
+    ASSERT_EQ(-888, AAUDIO_ERROR_NO_FREE_HANDLES);
+    ASSERT_EQ(-887, AAUDIO_ERROR_NO_MEMORY);
+    ASSERT_EQ(-886, AAUDIO_ERROR_NULL);
+    ASSERT_EQ(-885, AAUDIO_ERROR_TIMEOUT);
+    ASSERT_EQ(-884, AAUDIO_ERROR_WOULD_BLOCK);
+    ASSERT_EQ(-883, AAUDIO_ERROR_INVALID_FORMAT);
+    ASSERT_EQ(-882, AAUDIO_ERROR_OUT_OF_RANGE);
+    ASSERT_EQ(-881, AAUDIO_ERROR_NO_SERVICE);
+
+    ASSERT_EQ(0, AAUDIO_STREAM_STATE_UNINITIALIZED);
+    ASSERT_EQ(1, AAUDIO_STREAM_STATE_UNKNOWN);
+    ASSERT_EQ(2, AAUDIO_STREAM_STATE_OPEN);
+    ASSERT_EQ(3, AAUDIO_STREAM_STATE_STARTING);
+    ASSERT_EQ(4, AAUDIO_STREAM_STATE_STARTED);
+    ASSERT_EQ(5, AAUDIO_STREAM_STATE_PAUSING);
+    ASSERT_EQ(6, AAUDIO_STREAM_STATE_PAUSED);
+    ASSERT_EQ(7, AAUDIO_STREAM_STATE_FLUSHING);
+    ASSERT_EQ(8, AAUDIO_STREAM_STATE_FLUSHED);
+    ASSERT_EQ(9, AAUDIO_STREAM_STATE_STOPPING);
+    ASSERT_EQ(10, AAUDIO_STREAM_STATE_STOPPED);
+    ASSERT_EQ(11, AAUDIO_STREAM_STATE_CLOSING);
+    ASSERT_EQ(12, AAUDIO_STREAM_STATE_CLOSED);
+
+    ASSERT_EQ(0, AAUDIO_SHARING_MODE_EXCLUSIVE);
+    ASSERT_EQ(1, AAUDIO_SHARING_MODE_SHARED);
+
+    ASSERT_EQ(0, AAUDIO_CALLBACK_RESULT_CONTINUE);
+    ASSERT_EQ(1, AAUDIO_CALLBACK_RESULT_STOP);
+}
diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
index 1db2d72..736e0f3 100644
--- a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
+++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
@@ -53,6 +53,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.SynchronousQueue;
 import junit.framework.AssertionFailedError;
@@ -256,6 +257,32 @@
         assertStorageVolumesEquals(primary, childVolume);
     }
 
+    private void assertNoUuid(File file) {
+        try {
+            final UUID uuid = mStorageManager.getUuidForPath(file);
+            fail("Unexpected UUID " + uuid + " for " + file);
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testGetUuidForPath() throws Exception {
+        assertEquals(StorageManager.UUID_DEFAULT,
+                mStorageManager.getUuidForPath(Environment.getDataDirectory()));
+        assertEquals(StorageManager.UUID_DEFAULT,
+                mStorageManager.getUuidForPath(mContext.getDataDir()));
+
+        final UUID extUuid = mStorageManager
+                .getUuidForPath(Environment.getExternalStorageDirectory());
+        if (Environment.isExternalStorageEmulated()) {
+            assertEquals(StorageManager.UUID_DEFAULT, extUuid);
+        }
+
+        assertEquals(extUuid, mStorageManager.getUuidForPath(mContext.getExternalCacheDir()));
+
+        assertNoUuid(new File("/"));
+        assertNoUuid(new File("/proc/"));
+    }
+
     private static class TestProxyFileDescriptorCallback extends ProxyFileDescriptorCallback {
         final byte[] bytes;
         int fsyncCount;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
index e40f2ed..d8a80d2 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
@@ -131,6 +131,14 @@
         }
     }
 
+    private void maybeClick(UiSelector sel) {
+        try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
+    }
+
+    private void maybeClick(BySelector sel) {
+        try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
+    }
+
     /**
      * Verify that whoever handles {@link MediaStore#ACTION_IMAGE_CAPTURE} can
      * correctly write the contents into a passed {@code content://} Uri.
@@ -164,7 +172,7 @@
                 + pkg + " " + android.Manifest.permission.ACCESS_COARSE_LOCATION);
         getInstrumentation().getUiAutomation().executeShellCommand("pm grant "
                 + pkg + " " + android.Manifest.permission.ACCESS_FINE_LOCATION);
-        Thread.sleep(1000);
+        SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
 
         mActivity.startActivityForResult(intent, REQUEST_CODE);
         mDevice.waitForIdle();
@@ -184,15 +192,27 @@
         // Hrm, that didn't work; let's try an alternative approach of digging
         // around for a shutter button
         if (result == null) {
-            mDevice.findObject(new UiSelector().resourceId(pkg + ":id/shutter_button")).click();
+            maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
             mDevice.waitForIdle();
             SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-            mDevice.findObject(new UiSelector().resourceId(pkg + ":id/shutter_button")).click();
+            maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
             mDevice.waitForIdle();
+
+            result = mActivity.getResult(15, TimeUnit.SECONDS);
+            Log.d(TAG, "Second pass result was " + result);
         }
 
-        result = mActivity.getResult(15, TimeUnit.SECONDS);
-        Log.d(TAG, "Second pass result was " + result);
+        // Grr, let's try hunting around even more
+        if (result == null) {
+            maybeClick(By.pkg(pkg).descContains("Capture"));
+            mDevice.waitForIdle();
+            SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
+            maybeClick(By.pkg(pkg).descContains("Done"));
+            mDevice.waitForIdle();
+
+            result = mActivity.getResult(15, TimeUnit.SECONDS);
+            Log.d(TAG, "Third pass result was " + result);
+        }
 
         assertNotNull("Expected to get a IMAGE_CAPTURE result; your camera app should "
                 + "respond to the CAMERA and DPAD_CENTER keycodes", result);
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 420bba1..c01a173 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -555,7 +555,47 @@
             fail("Expected SecurityException. App does not have carrier privileges or is not the "
                     + "default dialer app");
         } catch (SecurityException expected) {
+        }
+    }
 
+    /**
+     * Tests that the device properly reports the contents of EF_FPLMN or null
+     */
+    @Test
+    public void testGetForbiddenPlmns() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        String[] plmns = mTelephonyManager.getForbiddenPlmns();
+
+        int phoneType = mTelephonyManager.getPhoneType();
+        switch (phoneType) {
+            case TelephonyManager.PHONE_TYPE_GSM:
+                assertNotNull("Forbidden PLMNs must be valid or an empty list!", plmns);
+            case TelephonyManager.PHONE_TYPE_CDMA:
+            case TelephonyManager.PHONE_TYPE_NONE:
+                if (plmns == null) {
+                    return;
+                }
+        }
+
+        for(String plmn : plmns) {
+            if (plmn.length() > 6 || plmn.length() < 5) {
+                fail("Invalid Length for PLMN-ID, must be 5 or 6: " + plmn);
+            }
+
+            // A record which is written in the SIM but empty will
+            // be all f's
+            if(android.text.TextUtils.isDigitsOnly(plmn)) {
+                assertTrue(
+                        "PLMNs must be strings of digits 0-9,F! " + plmn,
+                        android.text.TextUtils.isDigitsOnly(plmn));
+            } else {
+                for (char c : plmn.toUpperCase().toCharArray()) {
+                    assertTrue("PLMNs must be strings of digits 0-9,F! " + plmn,
+                            Character.toUpperCase(c) == 'F');
+                }
+            }
         }
     }
 
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index 589afe2..578591c 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -699,6 +699,14 @@
         Uri programUri = TvContract.buildPreviewProgramUri(programId);
         verifyPreviewProgram(programUri, values, programId);
 
+        values.remove(PreviewPrograms.COLUMN_TYPE);
+        try {
+            mContentResolver.insert(previewProgramsUri, values);
+            fail("Type should be a required column.");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+
         // Test: update
         values.put(PreviewPrograms.COLUMN_EPISODE_TITLE, "Sample title");
         values.put(PreviewPrograms.COLUMN_SHORT_DESCRIPTION, "Short description");
@@ -726,6 +734,14 @@
         Uri programUri = TvContract.buildWatchNextProgramUri(programId);
         verifyWatchNextProgram(programUri, values, programId);
 
+        values.remove(WatchNextPrograms.COLUMN_TYPE);
+        try {
+            mContentResolver.insert(watchNextProgramsUri, values);
+            fail("Type should be a required column.");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+
         // Test: update
         values.put(WatchNextPrograms.COLUMN_EPISODE_TITLE, "Sample title");
         values.put(WatchNextPrograms.COLUMN_SHORT_DESCRIPTION, "Short description");
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
index e3d56ba..95c222c3 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/AutofillHighlightTests.java
@@ -20,14 +20,17 @@
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class AutofillHighlightTests extends ActivityTestBase {
     @Test
     public void testHighlightedFrameLayout() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
index 77ff8f2..d705c7e 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -20,6 +20,7 @@
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.PerPixelBitmapVerifier;
@@ -27,8 +28,10 @@
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class BitmapFilterTests extends ActivityTestBase {
     private static final int WHITE_WEIGHT = 255 * 3;
     private enum FilterEnum {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapTests.java
index d9b8d7f..789d8d5 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapTests.java
@@ -24,6 +24,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Handler;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
@@ -41,7 +42,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class BitmapTests extends ActivityTestBase {
     class BitmapView extends View {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
index d9eec30..16f98f6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -26,11 +26,13 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.util.DisplayMetrics;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * Tests of state query-able from canvas at draw time.
@@ -39,6 +41,7 @@
  * capability to test the hardware accelerated Canvas in the way that it is used by Views.
  */
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class CanvasStateTests extends ActivityTestBase {
     @Test
     public void testClipRectReturnValues() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
index bbc50df..5d875ab 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
@@ -22,17 +22,19 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.PorterDuffXfermode;
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.util.List;
 
-@LargeTest // large while non-parameterized
-//@RunWith(Parameterized.class) // TODO: Reenable when CTS supports parameterized tests
+@MediumTest
+@RunWith(Parameterized.class)
 public class ColorFilterAlphaTest extends ActivityTestBase {
     // We care about one point in each of the four rectangles of different alpha values, as well as
     // the area outside the rectangles
@@ -85,12 +87,16 @@
                 0xFFC21A1A, 0xFFC93333, 0xFFD04D4D, 0xFFD66666, 0xFFBB0000 } },
     };
 
-    //@Parameterized.Parameters(name = "{0}")
+    @Parameterized.Parameters(name = "{0}")
     public static List<XfermodeTest.Config> configs() {
         return XfermodeTest.configs(MODES_AND_EXPECTED_COLORS);
     }
 
-    private XfermodeTest.Config mConfig;
+    private final XfermodeTest.Config mConfig;
+
+    public ColorFilterAlphaTest(XfermodeTest.Config config) {
+        mConfig = config;
+    }
 
     private static final int[] BLOCK_COLORS = new int[] {
             0x33808080,
@@ -127,12 +133,9 @@
 
     @Test
     public void test() {
-        for (XfermodeTest.Config config : configs()) {
-            mConfig = config;
-            createTest()
-                    .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
-                    .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
-        }
+        createTest()
+                .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
+                .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
     }
 }
 
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorSpaceTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorSpaceTests.java
index c5aa1b3..13c8e91 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorSpaceTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorSpaceTests.java
@@ -31,16 +31,19 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.io.InputStream;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ColorSpaceTests extends ActivityTestBase {
     private Bitmap mMask;
 
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 444af9f..304303a 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -25,6 +25,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.NinePatchDrawable;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.ExactComparer;
@@ -35,8 +36,10 @@
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ExactCanvasTests extends ActivityTestBase {
     private final BitmapComparer mExactComparer = new ExactComparer();
 
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
index 2a2ec51..ea7403b 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
@@ -22,6 +22,7 @@
 import android.graphics.Paint;
 import android.graphics.Typeface;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
@@ -29,8 +30,10 @@
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class FontRenderingTests extends ActivityTestBase {
     // Thresholds are barely loose enough for differences between sw and hw renderers.
     private static final double REGULAR_THRESHOLD = 0.92;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/GradientTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/GradientTests.java
index e808296..4b8b6b2 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/GradientTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/GradientTests.java
@@ -22,11 +22,14 @@
 import android.graphics.Point;
 import android.graphics.Shader;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class GradientTests extends ActivityTestBase {
     @Test
     public void testAlphaPreMultiplication() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
index 00b61e9..c62e134 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
@@ -28,6 +28,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 
 import android.graphics.Bitmap;
@@ -41,11 +42,13 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.io.InputStream;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class HardwareBitmapTests extends ActivityTestBase {
 
     private Resources mRes;
@@ -82,7 +85,7 @@
                     HARDWARE_OPTIONS);
             canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint());
         }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
-                R.drawable.golden_headless_robot, new ExactComparer()));
+                R.drawable.golden_headless_robot, new MSSIMComparer(0.95)));
     }
 
     @Test
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
index f952bc2..ee46601 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
@@ -18,7 +18,9 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
@@ -28,8 +30,10 @@
 import android.uirendering.cts.testinfrastructure.ViewInitializer;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class InfrastructureTests extends ActivityTestBase {
 
     @Test
@@ -45,6 +49,7 @@
      * by verifying that two paths that should render differently *do* render
      * differently.
      */
+    @LargeTest
     @Test
     public void testRenderSpecIsolation() {
         CanvasClient canvasClient = (canvas, width, height) -> {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index f7661a5..ed0110a 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -32,6 +32,7 @@
 import android.graphics.Rect;
 import android.graphics.Region.Op;
 import android.support.annotation.ColorInt;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
@@ -140,6 +141,7 @@
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
 
+    @LargeTest
     @Test
     public void testLayerClear() {
         ViewInitializer initializer = new ViewInitializer() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
index c0323b6..3d1c10e 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
@@ -18,14 +18,17 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class LayoutTests extends ActivityTestBase {
     @Test
     public void testSimpleRedLayout() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
index 6eaba8f..ae4fee1 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -24,7 +24,9 @@
 import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Typeface;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
@@ -38,10 +40,12 @@
 import android.webkit.WebView;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class PathClippingTests extends ActivityTestBase {
     // draw circle with hole in it, with stroked circle
     static final CanvasClient sTorusDrawCanvasClient = (canvas, width, height) -> {
@@ -173,6 +177,7 @@
         };
     }
 
+    @LargeTest
     @Test
     public void testWebViewClipWithCircle() {
         if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathTests.java
index 5abe831..2d5acaa 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathTests.java
@@ -5,14 +5,17 @@
 import android.graphics.Path;
 import android.graphics.Typeface;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class PathTests extends ActivityTestBase {
 
     private static final double REGULAR_THRESHOLD = 0.92;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
index c1e10d3..454eb2c0 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
@@ -22,13 +22,16 @@
 import android.graphics.Picture;
 import android.graphics.Rect;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class PictureTest extends ActivityTestBase {
 
     private static final Rect sRect = new Rect(0, 0, 40, 40);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/Rgba16fTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/Rgba16fTests.java
index 44831bf..d9ec2b5 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/Rgba16fTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/Rgba16fTests.java
@@ -25,16 +25,19 @@
 import android.graphics.Point;
 import android.graphics.Shader;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.io.InputStream;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class Rgba16fTests extends ActivityTestBase {
     @Test
     public void testTransferFunctions() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
index 2c9df73..252874d 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
@@ -27,14 +27,17 @@
 import android.graphics.RadialGradient;
 import android.graphics.Shader;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ShaderTests extends ActivityTestBase {
     @Test
     public void testSinglePixelBitmapShader() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
index e9b9bd4..e4f9809 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
@@ -18,14 +18,17 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.util.CompareUtils;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ShadowTests extends ActivityTestBase {
 
     private class GrayScaleVerifier extends SamplePointVerifier {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShapeTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShapeTests.java
index 9aad23d..0b708d4 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShapeTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShapeTests.java
@@ -17,14 +17,17 @@
 package android.uirendering.cts.testclasses;
 
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ShapeTests extends ActivityTestBase {
     @Test
     public void testDashedOval() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java
index 52b87cc..741c35c 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java
@@ -24,7 +24,9 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -40,10 +42,12 @@
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
 
-@MediumTest
+@LargeTest
+@RunWith(AndroidJUnit4.class)
 public class SurfaceViewTests extends ActivityTestBase {
 
     static final CanvasCallback sGreenCanvasCallback =
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
index c374dd7e..ff0e9a7 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
@@ -22,7 +22,9 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Shader;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -31,11 +33,13 @@
 import android.uirendering.cts.testinfrastructure.ResourceModifier;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * Test cases of all combination of resource modifications.
  */
-@MediumTest
+@LargeTest
+@RunWith(AndroidJUnit4.class)
 public class SweepTests extends ActivityTestBase {
     private final static DisplayModifier COLOR_FILTER_GRADIENT_MODIFIER = new DisplayModifier() {
         private final Rect mBounds = new Rect(30, 30, 150, 150);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/TextureViewTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/TextureViewTests.java
index f220bfb..abbec36 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/TextureViewTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/TextureViewTests.java
@@ -27,6 +27,7 @@
 import android.graphics.SurfaceTexture;
 import android.support.annotation.ColorInt;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -42,10 +43,12 @@
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class TextureViewTests extends ActivityTestBase {
 
     private static SurfaceTexture sRedTexture;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
index 2a64ac4..ffb263d 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
@@ -26,8 +26,10 @@
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class VectorDrawableTests extends ActivityTestBase {
     @Test
     public void testScaleDown() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewAnimationUtilsTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewAnimationUtilsTests.java
index d74dcb7..88aa265 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewAnimationUtilsTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewAnimationUtilsTests.java
@@ -17,6 +17,7 @@
 package android.uirendering.cts.testclasses;
 
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
@@ -25,8 +26,10 @@
 import android.view.ViewAnimationUtils;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ViewAnimationUtilsTests extends ActivityTestBase {
     @Test
     public void testCreateCircularReveal() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
index 47f9f4d..d1f0ee5 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
@@ -7,6 +7,7 @@
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
@@ -18,6 +19,7 @@
 import android.view.ViewOutlineProvider;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * This tests view clipping by modifying properties of blue_padded_layout, and validating
@@ -26,6 +28,7 @@
  * Since the layout is blue on a white background, this is always done with a RectVerifier.
  */
 @MediumTest
+@RunWith(AndroidJUnit4.class)
 public class ViewClippingTests extends ActivityTestBase {
     static final Rect FULL_RECT = new Rect(0, 0, 90, 90);
     static final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
index 04e1dfd..38a4d40 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
@@ -22,18 +22,20 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.RectF;
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.CanvasClient;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@LargeTest // large while non-parameterized
-//@RunWith(Parameterized.class) // TODO: Reenable when CTS supports parameterized tests
+@MediumTest
+@RunWith(Parameterized.class)
 public class XfermodeTest extends ActivityTestBase {
     /**
      * There are 4 locations we care about in testing each filter:
@@ -124,12 +126,16 @@
                 BG_COLOR, DST_COLOR, SCREEN_COLOR, SRC_COLOR } },
     };
 
-    //@Parameterized.Parameters(name = "{0}")
+    @Parameterized.Parameters(name = "{0}")
     public static List<Config> configs() {
         return configs(MODES_AND_EXPECTED_COLORS);
     }
 
-    private Config mConfig;
+    private final Config mConfig;
+
+    public XfermodeTest(Config config) {
+        mConfig = config;
+    }
 
     private CanvasClient mCanvasClient = new CanvasClient() {
         final Paint mPaint = new Paint();
@@ -170,11 +176,8 @@
 
     @Test
     public void test() {
-        for (XfermodeTest.Config config : configs()) {
-            mConfig = config;
-            createTest()
-                    .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
-                    .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
-        }
+        createTest()
+                .addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
+                .runWithVerifier(new SamplePointVerifier(TEST_POINTS, mConfig.expectedColors));
     }
 }
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 826116e..a2893d5 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -175,9 +175,6 @@
     <!-- b/31803630 -->
     <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.ListeningPortsTest" />
 
-    <!-- b/37108688 -->
-    <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.HardwareBufferTest#testCreate" />
-
     <!-- b/36686383 -->
     <option name="compatibility:exclude-filter" value="CtsIncidentHostTestCases com.android.server.cts.ErrorsTest#testANR" />