Merge "p2p: add group creation/join with band or freq tests"
diff --git a/Android.bp b/Android.bp
index 3eec2e6..2dce5de 100644
--- a/Android.bp
+++ b/Android.bp
@@ -49,3 +49,30 @@
         ],
     },
 }
+
+// Used with an android_test / android_test_helper_app, this is equivalent to
+// BUILD_CTS_SUPPORT_PACKAGE
+java_defaults {
+    name: "cts_support_defaults",
+    defaults: ["cts_error_prone_rules_tests"],
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+}
+
+// Used with different module types, this is equivalent to:
+//   android_test: BUILD_CTS_PACKAGE
+//   java_library: BUILD_CTS_TARGET_JAVA_LIBRARY
+//   java_library_host: BUILD_CTS_HOST_JAVA_LIBRARY
+java_defaults {
+    name: "cts_defaults",
+    defaults: ["cts_support_defaults"],
+    target: {
+        android: {
+            static_libs: ["platform-test-annotations"],
+        },
+    },
+}
diff --git a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
index 97b12ab..7923f95 100644
--- a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
+++ b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
@@ -19,7 +19,7 @@
 import its.target
 
 NUM_STEPS = 3
-ERROR_TOLERANCE = 0.97  # Allow ISO to be rounded down by 3%
+ERROR_TOLERANCE = 0.96  # Allow ISO to be rounded down by 4%
 
 
 def main():
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 9f86553..c5e2d1b 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -343,12 +343,13 @@
         p0_filtered = p0[mask]
         num_features = len(p0_filtered)
         if num_features < MIN_FEATURE_PTS:
-            print "Not enough feature points in frame", i
+            print "Not enough feature points in frame %s" % str(i-1).zfill(3)
             print "Need at least %d features, got %d" % (
                     MIN_FEATURE_PTS, num_features)
             assert 0
         else:
-            print "Number of features in frame %d is %d" % (i, num_features)
+            print "Number of features in frame %s is %d" % (
+                    str(i-1).zfill(3), num_features)
         p1, st, _ = cv2.calcOpticalFlowPyrLK(gframe0, gframe1, p0_filtered,
                                              None, **LK_PARAMS)
         tform = procrustes_rotation(p0_filtered[st == 1], p1[st == 1])
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 61dd69d..3f759ec 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1285,7 +1285,6 @@
             <meta-data android:name="test_category" android:value="@string/test_category_security" />
             <meta-data android:name="test_excluded_features"
                 android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
-            <meta-data android:name="test_required_features" android:value="android.hardware.fingerprint" />
         </activity>
 
         <activity android:name=".security.ScreenLockBoundKeysTest"
@@ -2137,6 +2136,16 @@
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
+        <activity android:name=".wifi.TestListActivity"
+                  android:label="@string/wifi_test"
+                  android:configChanges="keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_networking" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.wifi" />
+        </activity>
         <activity android:name=".wifiaware.TestListActivity"
                   android:label="@string/aware_test"
                   android:configChanges="keyboardHidden|orientation|screenSize">
@@ -2305,6 +2314,18 @@
                     android:value="android.hardware.type.watch:android.hardware.type.television:android.software.leanback" />
         </activity>
 
+        <activity android:name=".wifi.NetworkRequestSpecificNetworkSpecifierTestActivity"
+                  android:label="@string/wifi_test_network_request_specific"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".wifi.NetworkRequestPatternNetworkSpecifierTestActivity"
+                  android:label="@string/wifi_test_network_request_pattern"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".wifi.NetworkRequestUnavailableNetworkSpecifierTestActivity"
+                  android:label="@string/wifi_test_network_request_unavailable"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <activity android:name=".p2p.GoNegRequesterTestListActivity"
                 android:label="@string/p2p_go_neg_requester"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
diff --git a/apps/CtsVerifier/res/layout/wifi_main.xml b/apps/CtsVerifier/res/layout/wifi_main.xml
new file mode 100644
index 0000000..fee710d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/wifi_main.xml
@@ -0,0 +1,51 @@
+<?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"
+>
+
+    <FrameLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1.0"
+    >
+
+        <ScrollView android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+        >
+            <TextView android:id="@+id/wifi_info"
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      style="@style/InstructionsFont"
+            />
+        </ScrollView>
+
+        <ProgressBar
+            android:id="@+id/wifi_progress"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:indeterminate="true"
+            android:layout_gravity="center"
+            android:visibility="gone"
+        />
+    </FrameLayout>
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 60dd6f9..66c8f86 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1431,6 +1431,44 @@
     <string name="sv_failed_title">Test Failed</string>
     <string name="sv_failed_message">Unable to play stream.  See log for details.</string>
 
+    <!-- Strings for TestListActivity -->
+    <string name="wifi_test">Wi-Fi Test</string>
+    <string name="wifi_test_info">
+        The Wi-Fi tests requires an open (no security) access point along with the DUT.
+    </string>
+    <string name="wifi_location_not_enabled">Wi-Fi / Location Mode is not enabled</string>
+    <string name="wifi_location_not_enabled_message">These tests require Wi-Fi and Location Mode to be enabled.
+        Click the button below to go to system settings and enable Wi-Fi and Location Mode.</string>
+    <string name="wifi_settings">Wi-Fi Settings</string>
+    <string name="location_settings">Location Settings</string>
+    <string name="wifi_setup_error">
+        Test failed.\n\nSet up error. Check whether Wi-Fi is enabled.</string>
+    <string name="wifi_unexpected_error">
+        Test failed.\n\nUnexpected error. Check logcat.</string>
+
+    <string name="wifi_status_initiating_scan">Initiating scan.</string>
+    <string name="wifi_status_scan_failure">Unable to initiate scan.</string>
+    <string name="wifi_status_open_network_not_found">Unable to find any open network in scan results.</string>
+    <string name="wifi_status_initiating_network_request">Initiating network request.</string>
+    <string name="wifi_status_network_wait_for_available">Waiting for network connection. Please click the network in the dialog that pops up for approving the request.</string>
+    <string name="wifi_status_network_available">"Connected to network."</string>
+    <string name="wifi_status_network_wait_for_unavailable">"Ensuring device does not connect to any network. You should see an empty dialog that pops up for approving the request."</string>
+    <string name="wifi_status_network_unavailable">"Did not connect to any network."</string>
+    <string name="wifi_status_network_wait_for_lost">Ensuring device does not disconnect from the network until the request is released.</string>
+    <string name="wifi_status_network_lost">Disconnected from the network.</string>
+    <string name="wifi_status_network_cb_timeout">Network callback timed out.</string>
+
+    <string name="wifi_status_test_success">Test completed successfully!</string>
+    <string name="wifi_status_test_failed">Test failed!</string>
+
+    <string name="wifi_test_network_request">Network Request tests</string>
+    <string name="wifi_test_network_request_specific">Network Request with a specific SSID and BSSID.</string>
+    <string name="wifi_test_network_request_specific_info">Tests whether the API can be used to a connect to network with a specific SSID and BSSID specified in the request.</string>
+    <string name="wifi_test_network_request_pattern">Network Request with a SSID and BSSID pattern.</string>
+    <string name="wifi_test_network_request_pattern_info">Tests whether the API can be used to a connect to network with a SSID and BSSID pattern specified in the request.</string>
+    <string name="wifi_test_network_request_unavailable">Network Request with a specific network that is unavailable.</string>
+    <string name="wifi_test_network_request_unavailable_info">Tests that the API fails to connect when an unavailable network is specified in the request.</string>
+
     <!-- Strings for P2pTestActivity -->
     <string name="p2p_test">Wi-Fi Direct Test</string>
     <string name="p2p_test_info">
@@ -1654,6 +1692,7 @@
     <string name="aware_status_network_requested">Network requested ...</string>
     <string name="aware_status_network_success">Network formed ...</string>
     <string name="aware_status_network_failed">Network request failure - timed out!</string>
+    <string name="aware_status_network_failed_leak">Failure: Network request success - but leaked information!</string>
     <string name="aware_status_sleeping_wait_for_responder">Pausing to let Responder time to set up ...</string>
     <string name="aware_status_ranging_peer_failure">Ranging to PeerHandle failure: %1$d failures of %2$d attempts!</string>
     <string name="aware_status_ranging_mac_failure">Ranging to MAC address failure: %1$d failures of %2$d attempts!</string>
@@ -3466,7 +3505,7 @@
     <string name="disallow_remove_user">Disallow remove user</string>
     <string name="device_owner_disallow_remove_user_info">
         Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
-        \'Set restriction\' button to set the user restriction. 
+        \'Set restriction\' button to set the user restriction.
         Then press \'Go\' to open \'Multiple users\' setting. \n\n
 
         Mark this test as passed if:\n\n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
index 61abeae..31b43b4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
@@ -39,7 +39,7 @@
 /**
  * Manual test for BiometricManager and BiometricPrompt. This tests two things currently.
  * 1) When no biometrics are enrolled, BiometricManager and BiometricPrompt both return consistent
- *    BIOMETRIC_ERROR_NO_BIOMETRICS errors).
+ *    BIOMETRIC_ERROR_NONE_ENROLLED errors).
  * 2) When biometrics are enrolled, BiometricManager returns BIOMETRIC_SUCCESS and BiometricPrompt
  *    authentication can be successfully completed.
  */
@@ -152,7 +152,7 @@
         int result = mBiometricManager.canAuthenticate();
 
         if (testType == TEST_NONE_ENROLLED) {
-            if (result == BiometricManager.BIOMETRIC_ERROR_NO_BIOMETRICS) {
+            if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
                 mExpectedError = BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS;
                 showBiometricPrompt();
             } else {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 8f762c7..f3fe451 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -364,7 +364,8 @@
                 // Initialize memory quota on this device
                 for (String camId : devices) {
                     CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(camId);
-                    Size maxYuvSize = ItsUtils.getYuvOutputSizes(chars)[0];
+                    Size maxYuvSize = ItsUtils.getMaxOutputSize(
+                            mCameraCharacteristics, ImageFormat.YUV_420_888);
                     // 4 bytes per pixel for RGBA8888 Bitmap and at least 3 Bitmaps per CDD
                     int quota = maxYuvSize.getWidth() * maxYuvSize.getHeight() * 4 * 3;
                     if (quota > mMemoryQuota) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
index eb84d1e..c710490 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -53,19 +53,22 @@
 
         ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
 
-        adapter.add(TestListItem.newCategory(this, R.string.nfc_pee_2_pee));
-        adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_sender,
-                NdefPushSenderActivity.class.getName(),
-                new Intent(this, NdefPushSenderActivity.class), null));
-        adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_receiver,
-                NdefPushReceiverActivity.class.getName(),
-                new Intent(this, NdefPushReceiverActivity.class), null));
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)) {
+            adapter.add(TestListItem.newCategory(this, R.string.nfc_pee_2_pee));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_sender,
+                    NdefPushSenderActivity.class.getName(),
+                    new Intent(this, NdefPushSenderActivity.class), null));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_receiver,
+                    NdefPushReceiverActivity.class.getName(),
+                    new Intent(this, NdefPushReceiverActivity.class), null));
 
-        if ("MNC".equals(Build.VERSION.CODENAME) || Build.VERSION.SDK_INT >= 23) {
-            adapter.add(TestListItem.newTest(this, R.string.nfc_llcp_version_check,
-                    LlcpVersionActivity.class.getName(),
-                    new Intent(this, LlcpVersionActivity.class), null));
+            if ("MNC".equals(Build.VERSION.CODENAME) || Build.VERSION.SDK_INT >= 23) {
+                adapter.add(TestListItem.newTest(this, R.string.nfc_llcp_version_check,
+                        LlcpVersionActivity.class.getName(),
+                        new Intent(this, LlcpVersionActivity.class), null));
+            }
         }
+
         adapter.add(TestListItem.newCategory(this, R.string.nfc_tag_verification));
         adapter.add(TestListItem.newTest(this, R.string.nfc_ndef,
                 NDEF_ID, getTagIntent(Ndef.class), null));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
index 7fece23..d1a480d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
@@ -17,20 +17,31 @@
 package com.android.cts.verifier.security;
 
 import android.content.DialogInterface;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
+import android.widget.Button;
 
 import com.android.cts.verifier.R;
 
 import java.util.concurrent.Executor;
 
+/**
+ * Test for {@link BiometricPrompt}. This test runs twice, once with confirmation required,
+ * once without. Both tests use crypto objects.
+ */
 public class BiometricPromptBoundKeysTest extends FingerprintBoundKeysTest {
 
+    private static final int STATE_TEST_REQUIRE_CONFIRMATION = 1; // confirmation required
+    private static final int STATE_TEST_NO_CONFIRMATION = 2; // no confirmation required
+
     private DialogCallback mDialogCallback;
     private BiometricPrompt mBiometricPrompt;
     private CancellationSignal mCancellationSignal;
+    private BiometricManager mBiometricManager;
+    private int mState = STATE_TEST_REQUIRE_CONFIRMATION;
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
@@ -52,8 +63,15 @@
         @Override
         public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
             if (tryEncrypt()) {
-                showToast("Test passed.");
-                getPassButton().setEnabled(true);
+                if (mState == STATE_TEST_REQUIRE_CONFIRMATION) {
+                    mState = STATE_TEST_NO_CONFIRMATION;
+                    showToast("First test passed, run again to start the second test");
+                    Button startButton = findViewById(R.id.sec_start_test_button);
+                    startButton.setText("Run second test");
+                } else if (mState == STATE_TEST_NO_CONFIRMATION) {
+                    showToast("Test passed.");
+                    getPassButton().setEnabled(true);
+                }
             } else {
                 showToast("Test failed. Key not accessible after auth");
             }
@@ -61,9 +79,28 @@
     }
 
     @Override
+    protected void onPermissionsGranted() {
+        mBiometricManager = getSystemService(BiometricManager.class);
+        final int result = mBiometricManager.canAuthenticate();
+
+        if (result == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
+            showToast("No biometric features, test passed.");
+            getPassButton().setEnabled(true);
+        } else if (result == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+            showToast("Biometric unavailable, something is wrong with your device");
+        } else if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
+            showToast("Error: " + result + " Please ensure you have a biometric enrolled");
+            Button startTestButton = findViewById(R.id.sec_start_test_button);
+            startTestButton.setEnabled(false);
+        }
+    }
+
+    @Override
     protected void showAuthenticationScreen() {
         mCancellationSignal = new CancellationSignal();
         mDialogCallback = new DialogCallback();
+        final boolean requireConfirmation = mState == STATE_TEST_REQUIRE_CONFIRMATION
+                ? true : false;
         mBiometricPrompt = new BiometricPrompt.Builder(getApplicationContext())
                 .setTitle("Authenticate with biometric")
                 .setNegativeButton("Cancel", mExecutor,
@@ -72,6 +109,7 @@
                                 mHandler.post(mNegativeButtonRunnable);
                             }
                         })
+                .setRequireConfirmation(requireConfirmation)
                 .build();
         mBiometricPrompt.authenticate(
                 new BiometricPrompt
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
index 1ae7a12..4ad8e09 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
@@ -66,7 +66,7 @@
     private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
     private static final int AUTHENTICATION_DURATION_SECONDS = 2;
     private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1;
-    private static final int FINGERPRINT_PERMISSION_REQUEST_CODE = 0;
+    private static final int BIOMETRIC_REQUEST_PERMISSION_CODE = 0;
 
     protected boolean useStrongBox;
 
@@ -90,17 +90,17 @@
         setPassFailButtonClickListeners();
         setInfoResources(getTitleRes(), getDescriptionRes(), -1);
         getPassButton().setEnabled(false);
-        requestPermissions(new String[]{Manifest.permission.USE_FINGERPRINT},
-                FINGERPRINT_PERMISSION_REQUEST_CODE);
+        requestPermissions(new String[]{Manifest.permission.USE_BIOMETRIC},
+                BIOMETRIC_REQUEST_PERMISSION_CODE);
     }
 
     @Override
     public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
-        if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE && state[0] == PackageManager.PERMISSION_GRANTED) {
+        if (requestCode == BIOMETRIC_REQUEST_PERMISSION_CODE && state[0] == PackageManager.PERMISSION_GRANTED) {
             useStrongBox = false;
             mFingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
-            mKeyguardManager = (KeyguardManager) getSystemService(KeyguardManager.class);
-            Button startTestButton = (Button) findViewById(R.id.sec_start_test_button);
+            mKeyguardManager = getSystemService(KeyguardManager.class);
+            Button startTestButton = findViewById(R.id.sec_start_test_button);
 
             if (!mKeyguardManager.isKeyguardSecure()) {
                 // Show a message that the user hasn't set up a lock screen.
@@ -108,13 +108,10 @@
                                 + "Go to 'Settings -> Security -> Screen lock' to set up a lock screen");
                 startTestButton.setEnabled(false);
                 return;
-            } else if (!mFingerprintManager.hasEnrolledFingerprints()) {
-                showToast("No fingerprints enrolled.\n"
-                                + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint");
-                startTestButton.setEnabled(false);
-                return;
             }
 
+            onPermissionsGranted();
+
             startTestButton.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -124,6 +121,19 @@
         }
     }
 
+    /**
+     * Fingerprint-specific check before allowing test to be started
+     */
+    protected void onPermissionsGranted() {
+        mFingerprintManager = getSystemService(FingerprintManager.class);
+        if (!mFingerprintManager.hasEnrolledFingerprints()) {
+            showToast("No fingerprints enrolled.\n"
+                    + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint");
+            Button startTestButton = findViewById(R.id.sec_start_test_button);
+            startTestButton.setEnabled(false);
+        }
+    }
+
     protected void startTest() {
         createKey(false /* hasValidityDuration */);
         prepareEncrypt();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
index 789de68..9fbeba2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
@@ -167,7 +167,7 @@
 
             // acquire a partial wake lock just in case CPU fall asleep
             PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
                     "RVCVXCheckAnalyzer");
 
             wl.acquire();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
new file mode 100644
index 0000000..3d507cd
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Base class for Wifi tests.
+ */
+public abstract class BaseTestActivity extends PassFailButtons.Activity implements
+        BaseTestCase.Listener {
+    /*
+     * Handles to GUI elements.
+     */
+    private TextView mWifiInfo;
+    private ProgressBar mWifiProgress;
+
+    /*
+     * Test case to be executed
+     */
+    private BaseTestCase mTestCase;
+
+    private Handler mHandler = new Handler();
+
+    protected abstract BaseTestCase getTestCase(Context context);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.wifi_main);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        // Get UI component.
+        mWifiInfo = (TextView) findViewById(R.id.wifi_info);
+        mWifiProgress = (ProgressBar) findViewById(R.id.wifi_progress);
+
+        // Initialize test components.
+        mTestCase = getTestCase(this);
+
+        // keep screen on while this activity is front view.
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mTestCase.start(this);
+        mWifiProgress.setVisibility(View.VISIBLE);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mTestCase.stop();
+        mWifiProgress.setVisibility(View.GONE);
+    }
+
+    @Override
+    public void onTestStarted() {
+        // nop
+    }
+
+    @Override
+    public void onTestMsgReceived(String msg) {
+        if (msg == null) {
+            return;
+        }
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mWifiInfo.append(msg);
+                mWifiInfo.append("\n");
+            }
+        });
+    }
+
+    @Override
+    public void onTestSuccess() {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                getPassButton().setEnabled(true);
+                mWifiInfo.append(getString(R.string.wifi_status_test_success));
+                mWifiInfo.append("\n");
+                mWifiProgress.setVisibility(View.GONE);
+            }
+        });
+    }
+
+    @Override
+    public void onTestFailed(String reason) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (reason != null) {
+                    mWifiInfo.append(reason);
+                }
+                getPassButton().setEnabled(false);
+                mWifiInfo.append(getString(R.string.wifi_status_test_failed));
+                mWifiInfo.append("\n");
+                mWifiProgress.setVisibility(View.GONE);
+            }
+        });
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
new file mode 100644
index 0000000..8382903
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Base class for all Wifi test cases.
+ */
+public abstract class BaseTestCase {
+    protected Context mContext;
+    protected Resources mResources;
+    protected Listener mListener;
+
+    private Thread mThread;
+    private HandlerThread mHandlerThread;
+    protected Handler mHandler;
+
+    protected WifiManager mWifiManager;
+
+    public BaseTestCase(Context context) {
+        mContext = context;
+        mResources = mContext.getResources();
+    }
+
+    /**
+     * Set up the test case. Executed once before test starts.
+     */
+    protected void setUp() {
+        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+    }
+
+    /**
+     * Tear down the test case. Executed after test finishes - whether on success or failure.
+     */
+    protected void tearDown() {
+        mWifiManager = null;
+    }
+
+    /**
+     * Execute test case.
+     *
+     * @return true on success, false on failure. In case of failure
+     */
+    protected abstract boolean executeTest() throws InterruptedException;
+
+    /**
+     * Returns a String describing the failure reason of the most recent test failure (not valid
+     * in other scenarios). Override to customize the failure string.
+     */
+    protected String getFailureReason() {
+        return mContext.getString(R.string.wifi_unexpected_error);
+    }
+
+    /**
+     * Start running the test case.
+     * <p>
+     * Test case is executed in another thread.
+     */
+    public void start(Listener listener) {
+        mListener = listener;
+
+        stop();
+        mHandlerThread = new HandlerThread("CtsVerifier-Wifi");
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mThread = new Thread(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        mListener.onTestStarted();
+                        try {
+                            setUp();
+                        } catch (Exception e) {
+                            mListener.onTestFailed(mContext.getString(R.string.wifi_setup_error));
+                            return;
+                        }
+
+                        try {
+                            if (executeTest()) {
+                                mListener.onTestSuccess();
+                            } else {
+                                mListener.onTestFailed(getFailureReason());
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            mListener.onTestFailed(
+                                    mContext.getString(R.string.aware_unexpected_error));
+                        } finally {
+                            tearDown();
+                        }
+                    }
+                });
+        mThread.start();
+    }
+
+    /**
+     * Stop the currently running test case.
+     */
+    public void stop() {
+        if (mThread != null) {
+            mThread.interrupt();
+            mThread = null;
+        }
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+            mHandlerThread = null;
+            mHandler = null;
+        }
+    }
+
+    /**
+     * Listener interface used to communicate the state and status of the test case. It should
+     * be implemented by any activity encompassing a test case.
+     */
+    public interface Listener {
+        /**
+         * This function is invoked when the test case starts.
+         */
+        void onTestStarted();
+
+        /**
+         * This function is invoked by the test to send a message to listener.
+         */
+        void onTestMsgReceived(String msg);
+
+        /**
+         * This function is invoked when the test finished successfully.
+         */
+        void onTestSuccess();
+
+        /**
+         * This function is invoked when the test failed (test is done).
+         */
+        void onTestFailed(String reason);
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
new file mode 100644
index 0000000..b486852
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.util.Pair;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Blocking callbacks for Wi-Fi and Connectivity Manager.
+ */
+public class CallbackUtils {
+    public static final int DEFAULT_CALLBACK_TIMEOUT_MS = 15_000;
+
+    /**
+     * Utility NetworkCallback- provides mechanism to block execution with the
+     * waitForAttach method.
+     */
+    public static class NetworkCallback extends ConnectivityManager.NetworkCallback {
+        private final int mCallbackTimeoutInMs;
+
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+        private CountDownLatch mOnLostBlocker = new CountDownLatch(1);
+        private Network mNetwork;
+
+        public NetworkCallback() {
+            mCallbackTimeoutInMs = DEFAULT_CALLBACK_TIMEOUT_MS;
+        }
+
+        public NetworkCallback(int callbackTimeoutInMs) {
+            mCallbackTimeoutInMs = callbackTimeoutInMs;
+        }
+
+        @Override
+        public void onAvailable(Network network) {
+            mNetwork = network;
+            mBlocker.countDown();
+        }
+
+        @Override
+        public void onUnavailable() {
+            mBlocker.countDown();
+        }
+
+        @Override
+        public void onLost(Network network) {
+            mNetwork = network;
+            mOnLostBlocker.countDown();
+        }
+
+        /**
+         * Wait (blocks) for {@link #onAvailable(Network)} or timeout.
+         *
+         * @return A pair of values: whether the callback was invoked and the Network object
+         * created when successful - null otherwise.
+         */
+        public Pair<Boolean, Network> waitForAvailable() throws InterruptedException {
+            if (mBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+                return Pair.create(true, mNetwork);
+            }
+            return Pair.create(false, null);
+        }
+
+        /**
+         * Wait (blocks) for {@link #onUnavailable()} or timeout.
+         *
+         * @return true whether the callback was invoked.
+         */
+        public boolean waitForUnavailable() throws InterruptedException {
+            if (mBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Wait (blocks) for {@link #onLost(Network)} or timeout.
+         *
+         * @return true whether the callback was invoked.
+         */
+        public boolean waitForLost() throws InterruptedException {
+            if (mOnLostBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+                return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..b49f11d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_PATTERN_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with ssid/bssid pattern.
+ */
+public class NetworkRequestPatternNetworkSpecifierTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_PATTERN_SSID_BSSID);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_request_pattern,
+                R.string.wifi_test_network_request_pattern_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..7d82e8d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with specific ssid/bssid.
+ */
+public class NetworkRequestSpecificNetworkSpecifierTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_request_specific,
+                R.string.wifi_test_network_request_specific_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..c02c429
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with specific ssid/bssid not present in scan results.
+ */
+public class NetworkRequestUnavailableNetworkSpecifierTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_request_unavailable,
+                R.string.wifi_test_network_request_unavailable_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
new file mode 100644
index 0000000..1848dfd
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
@@ -0,0 +1,3 @@
+rpius@google.com
+etancohen@google.com
+satk@google.com
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
new file mode 100644
index 0000000..b4ccd3a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.location.LocationManager;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter;
+
+/**
+ * Activity listing all Wi-Fi Wifi tests.
+ */
+public class TestListActivity extends PassFailButtons.TestListActivity {
+    private static final String TAG = "TestListActivity";
+
+    private WifiManager mWifiManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        if (mWifiManager == null) {
+            Log.wtf(TAG,
+                    "Can't get WIFI_SERVICE. Should be gated by 'test_required_features'!?");
+            return;
+        }
+        setContentView(R.layout.pass_fail_list);
+        setInfoResources(R.string.wifi_test, R.string.wifi_test_info, 0);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        // Add the sub-test/categories
+        ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        adapter.add(TestListAdapter.TestListItem.newCategory(this,
+                R.string.wifi_test_network_request));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_request_specific,
+                NetworkRequestSpecificNetworkSpecifierTestActivity.class.getName(),
+                new Intent(this, NetworkRequestSpecificNetworkSpecifierTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_request_pattern,
+                NetworkRequestPatternNetworkSpecifierTestActivity.class.getName(),
+                new Intent(this, NetworkRequestPatternNetworkSpecifierTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_request_unavailable,
+                NetworkRequestUnavailableNetworkSpecifierTestActivity.class.getName(),
+                new Intent(this, NetworkRequestUnavailableNetworkSpecifierTestActivity.class),
+                null));
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+
+            @Override
+            public void onInvalidated() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+    }
+
+    @Override
+    protected void handleItemClick(ListView listView, View view, int position, long id) {
+        LocationManager locationManager =
+                (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+        if (!mWifiManager.isWifiEnabled() || !locationManager.isLocationEnabled()) {
+            showWifiAndLocationEnableDialog();
+            return;
+        }
+        super.handleItemClick(listView, view, position, id);
+    }
+
+    /**
+     * Show the dialog to jump to system settings in order to enable WiFi & location.
+     */
+    private void showWifiAndLocationEnableDialog() {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setIcon(android.R.drawable.ic_dialog_alert);
+        builder.setTitle(R.string.wifi_location_not_enabled);
+        builder.setMessage(R.string.wifi_location_not_enabled_message);
+        builder.setPositiveButton(R.string.wifi_settings,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+                    }
+                });
+        builder.setPositiveButton(R.string.location_settings,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+                    }
+                });
+        builder.create().show();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
new file mode 100644
index 0000000..5760ed2
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.wifi.testcase;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.MacAddress;
+import android.net.Network;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiNetworkConfigBuilder;
+import android.os.PatternMatcher;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.BaseTestCase;
+import com.android.cts.verifier.wifi.CallbackUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test case for all {@link NetworkRequest} requests with specifier built using
+ * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()}.
+ */
+public class NetworkRequestTestCase extends BaseTestCase {
+    private static final String TAG = "NetworkRequestTestCase";
+    private static final boolean DBG = true;
+
+    private static final String UNAVAILABLE_SSID = "blahblahblah";
+    private static final int NETWORK_REQUEST_TIMEOUT_MS = 30_000;
+    private static final int CALLBACK_TIMEOUT_MS = 40_000;
+    private static final int SCAN_TIMEOUT_MS = 30_000;
+
+    public static final int NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID = 0;
+    public static final int NETWORK_SPECIFIER_PATTERN_SSID_BSSID = 1;
+    public static final int NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID = 2;
+
+    @IntDef(prefix = { "NETWORK_SPECIFIER_" }, value = {
+            NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID,
+            NETWORK_SPECIFIER_PATTERN_SSID_BSSID,
+            NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NetworkSpecifierType{}
+
+    private final Object mLock = new Object();
+    private final @NetworkSpecifierType int mNetworkSpecifierType;
+
+    private ConnectivityManager mConnectivityManager;
+    private NetworkRequest mNetworkRequest;
+    private CallbackUtils.NetworkCallback mNetworkCallback;
+    private BroadcastReceiver mBroadcastReceiver;
+    private String mFailureReason;
+
+    public NetworkRequestTestCase(Context context, @NetworkSpecifierType int networkSpecifierType) {
+        super(context);
+        mNetworkSpecifierType = networkSpecifierType;
+    }
+
+    // Create a network specifier based on the test type.
+    private NetworkSpecifier createNetworkSpecifier(@NonNull ScanResult scanResult)
+            throws InterruptedException {
+        WifiNetworkConfigBuilder configBuilder = new WifiNetworkConfigBuilder();
+        switch (mNetworkSpecifierType) {
+            case NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID:
+                configBuilder.setSsid(scanResult.SSID);
+                configBuilder.setBssid(MacAddress.fromString(scanResult.BSSID));
+                break;
+            case NETWORK_SPECIFIER_PATTERN_SSID_BSSID:
+                String ssidPrefix = scanResult.SSID.substring(0, scanResult.SSID.length() - 1);
+                MacAddress bssidMask = MacAddress.fromString("ff:ff:ff:ff:ff:00");
+                configBuilder.setSsidPattern(
+                        new PatternMatcher(ssidPrefix, PatternMatcher.PATTERN_PREFIX));
+                configBuilder.setBssidPattern(MacAddress.fromString(scanResult.BSSID), bssidMask);
+                break;
+            case NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID:
+                String ssid = UNAVAILABLE_SSID;
+                MacAddress bssid = MacAddress.createRandomUnicastAddress();
+                if (findNetworkInScanResultsResults(ssid, bssid.toString())) {
+                    Log.e(TAG, "The specifiers chosen match a network in scan results."
+                            + "Test will fail");
+                    return null;
+                }
+                configBuilder.setSsid(UNAVAILABLE_SSID);
+                configBuilder.setBssid(bssid);
+                break;
+            default:
+                throw new IllegalStateException("Unknown specifier type specifier");
+        }
+        return configBuilder.buildNetworkSpecifier();
+    }
+
+    private boolean startScanAndWaitForResults() throws InterruptedException {
+        IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        // Scan Results available broadcast receiver.
+        mBroadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
+                if (!intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) return;
+                if (!intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) return;
+                if (DBG) Log.v(TAG, "Scan results received");
+                countDownLatch.countDown();
+            }
+        };
+        // Register the receiver for scan results broadcast.
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+        // Start scan.
+        if (DBG) Log.v(TAG, "Starting scan");
+        mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_initiating_scan));
+        if (!mWifiManager.startScan()) {
+            Log.e(TAG, "Failed to start scan");
+            setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+            return false;
+        }
+        // Wait for scan results.
+        if (DBG) Log.v(TAG, "Wait for scan results");
+        if (!countDownLatch.await(SCAN_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            Log.e(TAG, "No new scan results available");
+            setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+            return false;
+        }
+        return true;
+    }
+
+    // Helper to check if the scan result corresponds to an open network.
+    private static boolean isScanResultForOpenNetwork(@NonNull ScanResult scanResult) {
+        String capabilities = scanResult.capabilities;
+        return !capabilities.contains("PSK") && !capabilities.contains("EAP")
+                && !capabilities.contains("WEP") && !capabilities.contains("SAE")
+                && !capabilities.contains("SUITE-B-192") && !capabilities.contains("OWE");
+    }
+
+    private @Nullable ScanResult startScanAndFindAnyOpenNetworkInResults()
+            throws InterruptedException {
+        // Start scan and wait for new results.
+        if (!startScanAndWaitForResults()) {
+            return null;
+        }
+        // Filter results to find an open network.
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        for (ScanResult scanResult : scanResults) {
+            if (!TextUtils.isEmpty(scanResult.SSID)
+                    && !TextUtils.isEmpty(scanResult.BSSID)
+                    && isScanResultForOpenNetwork(scanResult)) {
+                if (DBG) Log.v(TAG, "Found open network " + scanResult);
+                return scanResult;
+            }
+        }
+        Log.e(TAG, "No open networks found in scan results");
+        setFailureReason(mContext.getString(R.string.wifi_status_open_network_not_found));
+        return null;
+    }
+
+    private boolean findNetworkInScanResultsResults(@NonNull String ssid, @NonNull String bssid)
+            throws InterruptedException {
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        for (ScanResult scanResult : scanResults) {
+            if (TextUtils.equals(scanResult.SSID, ssid)
+                    && TextUtils.equals(scanResult.BSSID, bssid)) {
+                if (DBG) Log.v(TAG, "Found network " + scanResult);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void setFailureReason(String reason) {
+        synchronized (mLock) {
+            mFailureReason = reason;
+        }
+    }
+
+    @Override
+    protected boolean executeTest() throws InterruptedException {
+        // Step 1: Scan and find any open network around.
+        if (DBG) Log.v(TAG, "Scan and find an open network");
+        ScanResult openNetwork = startScanAndFindAnyOpenNetworkInResults();
+        if (openNetwork == null) return false;
+
+        // Step 2: Create a specifier for the chosen open network depending on the type of test.
+        NetworkSpecifier wns = createNetworkSpecifier(openNetwork);
+        if (wns == null) return false;
+
+        // Step 3: Create a network request with specifier.
+        mNetworkRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI)
+                .setNetworkSpecifier(wns)
+                .removeCapability(NET_CAPABILITY_INTERNET)
+                .build();
+
+        // Step 4: Send the network request
+        if (DBG) Log.v(TAG, "Request network using " + mNetworkRequest);
+        mNetworkCallback = new CallbackUtils.NetworkCallback(CALLBACK_TIMEOUT_MS);
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_initiating_network_request));
+        mConnectivityManager.requestNetwork(mNetworkRequest, mNetworkCallback,
+                NETWORK_REQUEST_TIMEOUT_MS);
+
+        // Step 5: Wait for the network available/unavailable callback.
+        if (mNetworkSpecifierType == NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID) {
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_network_wait_for_unavailable));
+            if (DBG) Log.v(TAG, "Waiting for network unavailable callback");
+            boolean cbStatusForUnavailable = mNetworkCallback.waitForUnavailable();
+            if (!cbStatusForUnavailable) {
+                Log.e(TAG, "Failed to get network unavailable callback");
+                setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_network_unavailable));
+            // All done!
+            return true;
+        }
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_network_wait_for_available));
+        if (DBG) Log.v(TAG, "Waiting for network available callback");
+        Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
+        if (!cbStatusForAvailable.first) {
+            Log.e(TAG, "Failed to get network available callback");
+            setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+            return false;
+        }
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_network_available));
+
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_network_wait_for_lost));
+        // Step 6: Ensure we don't disconnect from the network as long as the request is alive.
+        if (DBG) Log.v(TAG, "Ensuring network lost callback is not invoked");
+        boolean cbStatusForLost = mNetworkCallback.waitForLost();
+        if (cbStatusForLost) {
+            Log.e(TAG, "Disconnected from the network even though the request is active");
+            setFailureReason(mContext.getString(R.string.wifi_status_network_lost));
+            return false;
+        }
+        // All done!
+        return true;
+    }
+
+    @Override
+    protected String getFailureReason() {
+        synchronized (mLock) {
+            return mFailureReason;
+        }
+    }
+
+    @Override
+    protected void setUp() {
+        super.setUp();
+        mConnectivityManager = ConnectivityManager.from(mContext);
+    }
+
+    @Override
+    protected void tearDown() {
+        if (mBroadcastReceiver != null) {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        }
+        if (mNetworkCallback != null) {
+            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+        }
+        super.tearDown();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
index 2bf4614..b1bd228 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
@@ -18,6 +18,7 @@
 
 import android.net.ConnectivityManager;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.wifi.aware.AttachCallback;
 import android.net.wifi.aware.DiscoverySessionCallback;
 import android.net.wifi.aware.IdentityChangedListener;
@@ -123,17 +124,18 @@
      */
     public static class NetworkCb extends ConnectivityManager.NetworkCallback {
         private CountDownLatch mBlocker = new CountDownLatch(1);
-        private boolean mNetworkAvailable = false;
+        private NetworkCapabilities mNetworkCapabilities = null;
 
         @Override
-        public void onAvailable(Network network) {
-            mNetworkAvailable = true;
+        public void onUnavailable() {
+            mNetworkCapabilities = null;
             mBlocker.countDown();
         }
 
         @Override
-        public void onUnavailable() {
-            mNetworkAvailable = false;
+        public void onCapabilitiesChanged(Network network,
+                NetworkCapabilities networkCapabilities) {
+            mNetworkCapabilities = networkCapabilities;
             mBlocker.countDown();
         }
 
@@ -142,11 +144,11 @@
          *
          * @return true if Available, false otherwise (Unavailable or timeout).
          */
-        public boolean waitForNetwork() throws InterruptedException {
+        public NetworkCapabilities waitForNetwork() throws InterruptedException {
             if (mBlocker.await(CALLBACK_TIMEOUT_SEC, TimeUnit.SECONDS)) {
-                return mNetworkAvailable;
+                return mNetworkCapabilities;
             }
-            return false;
+            return null;
         }
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
index fc8a3ef..2f9bf4c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
@@ -141,13 +141,18 @@
         mListener.onTestMsgReceived(
                 mContext.getString(R.string.aware_status_network_requested));
         if (DBG) Log.d(TAG, "executeTestSubscriber: requested network");
-        boolean networkAvailable = networkCb.waitForNetwork();
+        NetworkCapabilities nc = networkCb.waitForNetwork();
         cm.unregisterNetworkCallback(networkCb);
-        if (!networkAvailable) {
+        if (nc == null) {
             setFailureReason(mContext.getString(R.string.aware_status_network_failed));
             Log.e(TAG, "executeTestSubscriber: network request rejected - ON_UNAVAILABLE");
             return false;
         }
+        if (nc.getNetworkSpecifier() != null) {
+            setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+            Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+            return false;
+        }
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
         if (DBG) Log.d(TAG, "executeTestSubscriber: network request granted - AVAILABLE");
 
@@ -200,13 +205,18 @@
         }
 
         // 6. wait for network
-        boolean networkAvailable = networkCb.waitForNetwork();
+        NetworkCapabilities nc = networkCb.waitForNetwork();
         cm.unregisterNetworkCallback(networkCb);
-        if (!networkAvailable) {
+        if (nc == null) {
             setFailureReason(mContext.getString(R.string.aware_status_network_failed));
             Log.e(TAG, "executeTestPublisher: request network rejected - ON_UNAVAILABLE");
             return false;
         }
+        if (nc.getNetworkSpecifier() != null) {
+            setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+            Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+            return false;
+        }
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
         if (DBG) Log.d(TAG, "executeTestPublisher: network request granted - AVAILABLE");
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
index 0f81d2c..be198e1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
@@ -284,13 +284,18 @@
         cm.requestNetwork(nr, networkCb, CALLBACK_TIMEOUT_SEC * 1000);
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_requested));
         if (DBG) Log.d(TAG, "executeTestResponder: requested network");
-        boolean networkAvailable = networkCb.waitForNetwork();
+        NetworkCapabilities nc = networkCb.waitForNetwork();
         cm.unregisterNetworkCallback(networkCb);
-        if (!networkAvailable) {
+        if (nc == null) {
             setFailureReason(mContext.getString(R.string.aware_status_network_failed));
             Log.e(TAG, "executeTestResponder: network request rejected - ON_UNAVAILABLE");
             return false;
         }
+        if (nc.getNetworkSpecifier() != null) {
+            setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+            Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+            return false;
+        }
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
         if (DBG) Log.d(TAG, "executeTestResponder: network request granted - AVAILABLE");
 
@@ -418,13 +423,18 @@
         cm.requestNetwork(nr, networkCb, CALLBACK_TIMEOUT_SEC * 1000);
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_requested));
         if (DBG) Log.d(TAG, "executeTestInitiator: requested network");
-        boolean networkAvailable = networkCb.waitForNetwork();
+        NetworkCapabilities nc = networkCb.waitForNetwork();
         cm.unregisterNetworkCallback(networkCb);
-        if (!networkAvailable) {
+        if (nc == null) {
             setFailureReason(mContext.getString(R.string.aware_status_network_failed));
             Log.e(TAG, "executeTestInitiator: network request rejected - ON_UNAVAILABLE");
             return false;
         }
+        if (nc.getNetworkSpecifier() != null) {
+            setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+            Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+            return false;
+        }
         mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
         if (DBG) Log.d(TAG, "executeTestInitiator: network request granted - AVAILABLE");
 
diff --git a/build/host_java_library.mk b/build/host_java_library.mk
index 303527e..6db1995 100644
--- a/build/host_java_library.mk
+++ b/build/host_java_library.mk
@@ -17,6 +17,8 @@
 # Replace "include $(BUILD_HOST_JAVA_LIBRARY) with "include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 #
 
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
 -include cts/error_prone_rules_tests.mk
 
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/build/support_package.mk b/build/support_package.mk
index 83d7da9..6ab601f 100644
--- a/build/support_package.mk
+++ b/build/support_package.mk
@@ -18,6 +18,8 @@
 # Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_SUPPORT_PACKAGE)"
 #
 
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_support_defaults"
+
 # Disable by default so "m cts" will work in emulator builds
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/build/test_package.mk b/build/test_package.mk
index 2aa0852..e71a224 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -18,6 +18,8 @@
 # Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
 #
 
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
 LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
 
 -include cts/error_prone_rules_tests.mk
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index c932c30..0e36ca3 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -16,6 +16,8 @@
 # Builds a Java library.
 #
 
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
 # Disable by default so "m cts" will work in emulator builds
 LOCAL_DEX_PREOPT := false
 LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
diff --git a/common/device-side/device-info/Android.bp b/common/device-side/device-info/Android.bp
index 583bc85..f4c80ba 100644
--- a/common/device-side/device-info/Android.bp
+++ b/common/device-side/device-info/Android.bp
@@ -25,17 +25,7 @@
 
     libs: [
         "android.test.base.stubs",
-        "framework-stub-for-compatibility-device-info",
     ],
 
     sdk_version: "test_current",
 }
-
-java_library {
-    // This stub library provides some internal APIs (SystemProperties, VintfObject, etc.)
-    // to compatibility-device-info library.
-    name: "framework-stub-for-compatibility-device-info",
-    srcs: ["src_stub/**/*.java"],
-
-    sdk_version: "current",
-}
diff --git a/common/device-side/device-info/src_stub/android/os/SystemProperties.java b/common/device-side/device-info/src_stub/android/os/SystemProperties.java
deleted file mode 100644
index 2f8a051..0000000
--- a/common/device-side/device-info/src_stub/android/os/SystemProperties.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/SystemProperties.java
- */
-package android.os;
-
-public class SystemProperties {
-    public static String get(String key, String def) { return null; }
-}
diff --git a/common/device-side/device-info/src_stub/android/os/VintfObject.java b/common/device-side/device-info/src_stub/android/os/VintfObject.java
deleted file mode 100644
index b8da52e..0000000
--- a/common/device-side/device-info/src_stub/android/os/VintfObject.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/VintfObject.java
- */
-
-package android.os;
-
-import java.util.Map;
-
-public class VintfObject {
-    public static Map<String, String[]> getVndkSnapshots() { return null; }
-    public static String getSepolicyVersion() { return null; }
-    public static String[] getHalNamesAndVersions() { return null; }
-    public static String[] report() { return null; }
-    public static Long getTargetFrameworkCompatibilityMatrixVersion() { return null; }
-}
diff --git a/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java b/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java
deleted file mode 100644
index 20fa94c..0000000
--- a/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/VintfRuntimeInfo.java
- */
-package android.os;
-
-public class VintfRuntimeInfo {
-    public static String getBootAvbVersion() { return null; }
-    public static String getBootVbmetaAvbVersion() { return null; }
-    public static String getCpuInfo() { return null; }
-    public static String getHardwareId() { return null; }
-    public static String getKernelVersion() { return null; }
-    public static String getNodeName() { return null; }
-    public static String getOsName() { return null; }
-    public static String getOsRelease() { return null; }
-    public static String getOsVersion() { return null; }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
index a2439c7..cbb44c7 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
@@ -16,23 +16,59 @@
 
 package com.android.compatibility.common.util;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import android.graphics.Color;
 
+import androidx.annotation.NonNull;
+
+import java.util.function.IntUnaryOperator;
+
 public class ColorUtils {
     public static void verifyColor(int expected, int observed) {
         verifyColor(expected, observed, 0);
     }
 
     public static void verifyColor(int expected, int observed, int tolerance) {
-        String s = "expected " + Integer.toHexString(expected)
-                + ", observed " + Integer.toHexString(observed)
-                + ", tolerated channel error " + tolerance;
-        assertEquals(s, Color.red(expected), Color.red(observed), tolerance);
-        assertEquals(s, Color.green(expected), Color.green(observed), tolerance);
-        assertEquals(s, Color.blue(expected), Color.blue(observed), tolerance);
-        assertEquals(s, Color.alpha(expected), Color.alpha(observed), tolerance);
+        verifyColor("", expected, observed, tolerance);
+    }
+
+    /**
+     * Verify that two colors match within a per-channel tolerance.
+     *
+     * @param s String with extra information about the test with an error.
+     * @param expected Expected color.
+     * @param observed Observed color.
+     * @param tolerance Per-channel tolerance by which the color can mismatch.
+     */
+    public static void verifyColor(@NonNull String s, int expected, int observed, int tolerance) {
+        s += " expected 0x" + Integer.toHexString(expected)
+            + ", observed 0x" + Integer.toHexString(observed)
+            + ", tolerated channel error 0x" + tolerance;
+        String red = verifyChannel("red", expected, observed, tolerance, (i) -> Color.red(i));
+        String green = verifyChannel("green", expected, observed, tolerance, (i) -> Color.green(i));
+        String blue = verifyChannel("blue", expected, observed, tolerance, (i) -> Color.blue(i));
+        String alpha = verifyChannel("alpha", expected, observed, tolerance, (i) -> Color.alpha(i));
+
+        String err = null;
+        for (String channel : new String[]{red, green, blue, alpha}) {
+            if (channel == null) continue;
+            if (err == null) err = s;
+            err += "\n\t\t" + channel;
+        }
+        if (err != null) {
+            fail(err);
+        }
+    }
+
+    private static String verifyChannel(String channelName, int expected, int observed,
+            int tolerance, IntUnaryOperator f) {
+        int e = f.applyAsInt(expected);
+        int o = f.applyAsInt(observed);
+        if (Math.abs(e - o) <= tolerance) {
+            return null;
+        }
+        return "Channel " + channelName + " mismatch: expected<0x" + Integer.toHexString(e)
+            + ">, observed: <0x" + Integer.toHexString(o) + ">";
     }
 }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
index a153a4b..e7b6976 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
@@ -114,4 +114,21 @@
     private static PackageManager getPackageManager() {
         return InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
     }
+
+    private static boolean hasDeviceFeature(final String requiredFeature) {
+        return InstrumentationRegistry.getContext()
+                .getPackageManager()
+                .hasSystemFeature(requiredFeature);
+    }
+
+    /**
+     * Rotation support is indicated by explicitly having both landscape and portrait
+     * features or not listing either at all.
+     */
+    public static boolean supportsRotation() {
+        final boolean supportsLandscape = hasDeviceFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+        final boolean supportsPortrait = hasDeviceFeature(PackageManager.FEATURE_SCREEN_PORTRAIT);
+        return (supportsLandscape && supportsPortrait)
+                || (!supportsLandscape && !supportsPortrait);
+    }
 }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
index b858f5c..f3438ee 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
@@ -41,6 +41,20 @@
     }
 
     /**
+     * Utility interface to invoke a method against the target object.
+     *
+     * @param <U> the type of the object against which the method is invoked.
+     */
+    public interface ShellPermissionMethodHelperNoReturn<U> {
+        /**
+         * Invokes the method against the target object.
+         *
+         * @param targetObject the object against which the method should be invoked.
+         */
+        void callMethod(U targetObject);
+    }
+
+    /**
      * Invokes the specified method on the targetObject as the shell user. The method can be invoked
      * as follows:
      *
@@ -60,6 +74,25 @@
     }
 
     /**
+     * Invokes the specified method on the targetObject as the shell user. The method can be invoked
+     * as follows:
+     *
+     * {@code ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+     *        (tm) -> tm.getDeviceId());}
+     */
+    public static <U> void invokeMethodWithShellPermissionsNoReturn(
+            U targetObject, ShellPermissionMethodHelperNoReturn<U> methodHelper) {
+        final UiAutomation uiAutomation =
+                InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            methodHelper.callMethod(targetObject);
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
      * Utility interface to invoke a static method.
      *
      * @param <T> the type returned by the invoked method.
diff --git a/hostsidetests/angle/app/driverTest/Android.mk b/hostsidetests/angle/app/driverTest/Android.mk
index 9d8d629..37a1140 100644
--- a/hostsidetests/angle/app/driverTest/Android.mk
+++ b/hostsidetests/angle/app/driverTest/Android.mk
@@ -27,7 +27,7 @@
 LOCAL_SDK_VERSION := current
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 
 LOCAL_MULTILIB := both
 
diff --git a/hostsidetests/angle/app/driverTest/AndroidManifest.xml b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
index 03c3c53..be800a1 100755
--- a/hostsidetests/angle/app/driverTest/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.angleIntegrationTest.driverTest">
 
-    <application>
+    <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
 
         <activity android:name="com.android.angleIntegrationTest.common.AngleIntegrationTestActivity" >
diff --git a/hostsidetests/angle/app/driverTestSecondary/Android.mk b/hostsidetests/angle/app/driverTestSecondary/Android.mk
index 87855e8..d361192 100644
--- a/hostsidetests/angle/app/driverTestSecondary/Android.mk
+++ b/hostsidetests/angle/app/driverTestSecondary/Android.mk
@@ -27,7 +27,7 @@
 LOCAL_SDK_VERSION := current
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 
 LOCAL_MULTILIB := both
 
diff --git a/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
index 1d8f1a7..bd2739d 100755
--- a/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.angleIntegrationTest.driverTestSecondary">
 
-    <application>
+    <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
 
         <activity android:name="com.android.angleIntegrationTest.common.AngleIntegrationTestActivity" >
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
index 721de8f..a5d2262 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
@@ -26,13 +26,14 @@
     static final String SETTINGS_GLOBAL_ALL_USE_ANGLE = "angle_gl_driver_all_angle";
     static final String SETTINGS_GLOBAL_DRIVER_PKGS = "angle_gl_driver_selection_pkgs";
     static final String SETTINGS_GLOBAL_DRIVER_VALUES = "angle_gl_driver_selection_values";
+    static final String SETTINGS_GLOBAL_WHITELIST = "angle_whitelist";
 
     // System Properties
+    static final String PROPERTY_GFX_ANGLE_SUPPORTED = "ro.gfx.angle.supported";
     static final String PROPERTY_BUILD_TYPE = "ro.build.type";
     static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
     static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
     static final String PROPERTY_TEMP_RULES_FILE = "debug.angle.rules";
-    static final String PROPERTY_ENABLE_RULES_FILE = "debug.angle.enable";
 
     // Rules File
     static final String DEVICE_TEMP_RULES_FILE_DIRECTORY = "/data/local/tmp";
@@ -40,7 +41,6 @@
     static final String DEVICE_TEMP_RULES_FILE_PATH = DEVICE_TEMP_RULES_FILE_DIRECTORY + "/" + DEVICE_TEMP_RULES_FILE_FILENAME;
 
     // ANGLE
-    static final String ANGLE_PKG = "com.google.android.angle";
     static final String ANGLE_DRIVER_TEST_PKG = "com.android.angleIntegrationTest.driverTest";
     static final String ANGLE_DRIVER_TEST_SEC_PKG = "com.android.angleIntegrationTest.driverTestSecondary";
     static final String ANGLE_DRIVER_TEST_CLASS = "AngleDriverTestActivity";
@@ -85,17 +85,17 @@
         device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_ALL_USE_ANGLE, "0");
         device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS, "\"\"");
         device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES, "\"\"");
+        device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_WHITELIST, "\"\"");
         CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_TEMP_RULES_FILE, "\"\"");
-        CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "0");
     }
 
     static boolean isAngleLoadable(ITestDevice device) throws Exception {
-        PackageInfo anglePkgInfo = device.getAppPackageInfo(ANGLE_PKG);
+        String angleSupported = device.getProperty(PROPERTY_GFX_ANGLE_SUPPORTED);
         String propDisablePreloading = device.getProperty(PROPERTY_DISABLE_OPENGL_PRELOADING);
         String propGfxDriver = device.getProperty(PROPERTY_GFX_DRIVER);
 
         // Make sure ANGLE exists on the device
-        if(anglePkgInfo == null) {
+        if((angleSupported == null) || (angleSupported.equals("false"))) {
             return false;
         }
 
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
index cda98e3..385da2a 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
@@ -88,7 +88,6 @@
     public void setUp() throws Exception {
         CtsAngleCommon.clearSettings(getDevice());
 
-        CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_PKG);
         CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_PKG);
         CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG);
     }
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
index f4f495a..87281b9 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
@@ -67,8 +67,10 @@
     public void setUp() throws Exception {
         CtsAngleCommon.clearSettings(getDevice());
 
-        // Enable checking the rules file
-        CtsAngleCommon.setProperty(getDevice(), CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "1");
+        // Application must be whitelisted to load temp rules
+        getDevice().setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_WHITELIST,
+            CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," +
+            CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG);
     }
 
     @After
@@ -117,4 +119,4 @@
                 CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
                 CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
     }
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
index bbfc62f..d8a280e 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
@@ -117,6 +117,18 @@
             // Unmount, remount and verify
             getDevice().executeShellCommand("sm unmount " + vol.volId);
             getDevice().executeShellCommand("sm mount " + vol.volId);
+
+            int attempt = 0;
+            String pkgPath = getDevice().executeShellCommand("pm path " + PKG);
+            while ((pkgPath == null || pkgPath.isEmpty()) && attempt++ < 15) {
+                Thread.sleep(1000);
+                pkgPath = getDevice().executeShellCommand("pm path " + PKG);
+            }
+
+            if (pkgPath == null || pkgPath.isEmpty()) {
+                throw new AssertionError("Package not ready yet");
+            }
+
             runDeviceTests(PKG, CLASS, "testDataNotInternal");
             runDeviceTests(PKG, CLASS, "testDataRead");
             runDeviceTests(PKG, CLASS, "testNative");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
index 822edce..d7b812f 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
@@ -85,7 +85,8 @@
         } else {
             testArgs = null;
         }
-        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, testArgs);
+        Utils.runDeviceTestsAsCurrentUser(getDevice(), packageName, testClassName, testMethodName,
+                testArgs);
     }
 
     protected boolean isAppVisibleForUser(String packageName, int userId,
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index 82c94cf..ec66cd1 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -551,7 +551,7 @@
     }
 
     private boolean hasIsolatedStorage() throws DeviceNotAvailableException {
-        return getDevice().executeShellCommand("getprop persist.sys.isolated_storage")
+        return getDevice().executeShellCommand("getprop sys.isolated_storage_snapshot")
                 .contains("true");
     }
 
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 34f6100..2f503e3 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -276,6 +276,8 @@
         findDocument("DIR2").click();
         mDevice.waitForIdle();
         findSaveButton().click();
+        mDevice.waitForIdle();
+        findPositiveButton().click();
 
         final Result result = mActivity.getResult();
         final Uri uri = result.data.getData();
@@ -397,6 +399,8 @@
         findDocument("DIR2").click();
         mDevice.waitForIdle();
         findSaveButton().click();
+        mDevice.waitForIdle();
+        findPositiveButton().click();
 
         final Result result = mActivity.getResult();
         final Uri uri = result.data.getData();
@@ -504,6 +508,8 @@
         findDocument("DIR2").click();
         mDevice.waitForIdle();
         findSaveButton().click();
+        mDevice.waitForIdle();
+        findPositiveButton().click();
 
         final Result result = mActivity.getResult();
         final Uri uri = result.data.getData();
diff --git a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
index cc70445..d0373e1 100644
--- a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
+++ b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
@@ -72,12 +72,14 @@
         EXCEPTION_PATTERNS.add("127.0.0.1 10000");  // used by the cast receiver
         EXCEPTION_PATTERNS.add(":: 1002");          // used by remote control
         EXCEPTION_PATTERNS.add(":: 1020");          // used by remote control
+        EXCEPTION_PATTERNS.add("0.0.0.0:7275");     // used by supl
         //no current patterns involve address, port and UID combinations
         //Example for when necessary: EXCEPTION_PATTERNS.add("0.0.0.0:5555 10000")
 
         // IPv6 exceptions
         // TODO: this is not standard notation for IPv6. Use [$addr]:$port instead as per RFC 3986.
         EXCEPTION_PATTERNS.add(":::5555");          // emulator port for adb
+        EXCEPTION_PATTERNS.add(":::7275");          // used by supl
     }
 
     /**
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
index 1c2427a..20be2cc 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
@@ -16,13 +16,6 @@
 
 package com.android.cts.usepermission;
 
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
 
@@ -32,13 +25,11 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.Process;
 import android.provider.CalendarContract;
 
 import org.junit.Test;
 
-import java.io.File;
 import java.util.Arrays;
 
 /**
@@ -51,61 +42,42 @@
 
     @Test
     public void testCompatDefault() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+        // Legacy permission model appears granted
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                mContext.checkPermission(android.Manifest.permission.READ_CALENDAR,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                mContext.checkPermission(android.Manifest.permission.WRITE_CALENDAR,
+                        Process.myPid(), Process.myUid()));
 
-        // Legacy permission model is granted by default
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                mContext.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                mContext.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        for (File path : getAllPackageSpecificPaths(mContext)) {
-            if (path != null) {
-                assertDirReadWriteAccess(path);
-            }
+        // Read/write access should be allowed
+        final Uri uri = insertCalendarItem();
+        try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+            assertEquals(1, c.getCount());
         }
-        assertMediaReadWriteAccess(mContext.getContentResolver());
     }
 
     @Test
     public void testCompatRevoked_part1() throws Exception {
         // Revoke the permission
-        revokePermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, true);
-    }
-
-    private void assertNoStorageAccess() throws Exception {
-        assertEquals(Environment.MEDIA_UNMOUNTED, Environment.getExternalStorageState());
-
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        for (File dir : getAllPackageSpecificPaths(mContext)) {
-            if (dir != null) {
-                assertDirNoAccess(dir);
-            }
-        }
-        assertMediaNoAccess(mContext.getContentResolver(), true);
-
-        // Just to be sure, poke explicit path
-        assertDirNoAccess(new File(Environment.getExternalStorageDirectory(),
-                "/Android/data/" + mContext.getPackageName()));
+        revokePermissions(new String[] {Manifest.permission.WRITE_CALENDAR}, true);
     }
 
     @Test
     public void testCompatRevoked_part2() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // Legacy permission model appears granted, but storage looks and
-        // behaves like it's ejected
+        // Legacy permission model appears granted
         assertEquals(PackageManager.PERMISSION_GRANTED,
-                mContext.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                mContext.checkPermission(android.Manifest.permission.READ_CALENDAR,
                         Process.myPid(), Process.myUid()));
         assertEquals(PackageManager.PERMISSION_GRANTED,
-                mContext.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                mContext.checkPermission(android.Manifest.permission.WRITE_CALENDAR,
                         Process.myPid(), Process.myUid()));
 
-        assertNoStorageAccess();
+        // Read/write access should be ignored
+        final Uri uri = insertCalendarItem();
+        try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+            assertEquals(0, c.getCount());
+        }
     }
 
     @Test
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 806c551..3e3f040 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -17,6 +17,7 @@
 package com.android.cts.usepermission;
 
 import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
@@ -34,6 +35,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Direction;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObject2;
@@ -47,13 +49,16 @@
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ScrollView;
 import android.widget.Switch;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
 public abstract class BasePermissionsTest {
@@ -62,7 +67,7 @@
     private static final long IDLE_TIMEOUT_MILLIS = 500;
     private static final long GLOBAL_TIMEOUT_MILLIS = 5000;
 
-    private static final long RETRY_TIMEOUT = 3 * GLOBAL_TIMEOUT_MILLIS;
+    private static final long RETRY_TIMEOUT = 10 * GLOBAL_TIMEOUT_MILLIS;
     private static final String LOG_TAG = "BasePermissionsTest";
 
     private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();
@@ -289,36 +294,47 @@
 
     protected void clickAllowButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_allow_button")).click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_allow_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickAllowAlwaysButton() throws Exception {
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_allow_always_button")).click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_allow_always_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickAllowForegroundButton() throws Exception {
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_allow_foreground_only_button")).click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_allow_foreground_only_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDenyButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_deny_button")).click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_deny_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDenyAndDontAskAgainButton() throws Exception {
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")).click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDontAskAgainButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button"))
-                .click();
+        waitForIdle();
+        getUiDevice().wait(Until.findObject(By.res(
+                "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button")),
+                GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void grantPermission(String permission) throws Exception {
@@ -377,7 +393,6 @@
         Assert.assertNotNull("Permissions label should be present", permLabelView);
 
         AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);
-        Assert.assertNotNull("Permissions item should be present", permItemView);
 
         click(permItemView);
 
@@ -387,36 +402,34 @@
             // Find the permission screen
             String permissionLabel = getPermissionLabel(permission);
 
-            AccessibilityNodeInfo labelView = getNodeTimed(() -> findByText(permissionLabel), true);
-            Assert.assertNotNull("Permission label should be present", labelView);
+            UiObject2 permissionView = null;
+            long start = System.currentTimeMillis();
+            while (permissionView == null && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
+                permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
+                        GLOBAL_TIMEOUT_MILLIS);
 
-            AccessibilityNodeInfo itemView = findCollectionItem(labelView);
-            Assert.assertNotNull("Permission item should be present", itemView);
+                if (permissionView == null) {
+                    getUiDevice().findObject(By.res("android:id/list_container"))
+                            .scroll(Direction.DOWN, 1);
+                }
+            }
 
-            click(itemView);
+            permissionView.click();
+            waitForIdle();
 
             String denyLabel = mContext.getResources().getString(R.string.Deny);
-            AccessibilityNodeInfo denyView = getNodeTimed(() -> findByText(denyLabel), true);
-            Assert.assertNotNull("Deny label should be present", denyView);
 
-            final boolean wasGranted = !denyView.isChecked();
+            final boolean wasGranted = !getUiDevice().wait(Until.findObject(By.text(denyLabel)),
+                    GLOBAL_TIMEOUT_MILLIS).isChecked();
             if (granted != wasGranted) {
                 // Toggle the permission
 
                 if (granted) {
                     String allowLabel = mContext.getResources().getString(R.string.Allow);
-                    AccessibilityNodeInfo allowView = getNodeTimed(() -> findByText(allowLabel), false);
-                    if (allowView == null) {
-                        String allowAllLabel = mContext.getResources().getString(R.string.AllowAll);
-                        allowView = getNodeTimed(() -> findByText(allowAllLabel), true);
-                    }
-                    Assert.assertNotNull("Allow label should be present", allowView);
-
-                    click(allowView);
+                    getUiDevice().findObject(By.text(allowLabel)).click();
                 } else {
-                    click(denyView);
+                    getUiDevice().findObject(By.text(denyLabel)).click();
                 }
-
                 waitForIdle();
 
                 if (wasGranted && legacyApp) {
@@ -429,9 +442,8 @@
                             .createPackageContext(packageName, 0).getResources();
                     final int confirmResId = resources.getIdentifier(resIdName, null, null);
                     String confirmTitle = resources.getString(confirmResId);
-                    UiObject denyAnyway = getUiDevice().findObject(new UiSelector()
-                            .textStartsWith(confirmTitle));
-                    denyAnyway.click();
+                    getUiDevice().wait(Until.findObject(By.textStartsWith(confirmTitle)),
+                            GLOBAL_TIMEOUT_MILLIS).click();
 
                     waitForIdle();
                 }
@@ -585,27 +597,6 @@
         return null;
     }
 
-    private static AccessibilityNodeInfo findSwitch(AccessibilityNodeInfo root) throws Exception {
-        if (Switch.class.getName().equals(root.getClassName().toString())) {
-            return root;
-        }
-        final int childCount = root.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            AccessibilityNodeInfo child = root.getChild(i);
-            if (child == null) {
-                continue;
-            }
-            if (Switch.class.getName().equals(child.getClassName().toString())) {
-                return child;
-            }
-            AccessibilityNodeInfo result = findSwitch(child);
-            if (result != null) {
-                return result;
-            }
-        }
-        return null;
-    }
-
     private static AccessibilityNodeInfo getNodeTimed(
             Callable<AccessibilityNodeInfo> callable, boolean retry) throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index 06c2b35..ed74947 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -20,15 +20,13 @@
 
 import static org.junit.Assert.fail;
 
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
 import android.Manifest;
+import android.content.ContentValues;
+import android.content.Context;
 import android.content.pm.PackageManager;
-import android.os.Environment;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.CalendarContract;
 import android.support.test.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -40,6 +38,8 @@
 public class UsePermissionTest23 extends BasePermissionsTest {
     private static final int REQUEST_CODE_PERMISSIONS = 42;
 
+    private final Context mContext = getInstrumentation().getContext();
+
     private boolean mLeanback;
     private boolean mWatch;
 
@@ -62,49 +62,47 @@
 
     @Test
     public void testDefault() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
         // New permission model is denied by default
         assertAllPermissionsRevoked();
-
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
     }
 
     @Test
     public void testGranted() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-        grantPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
+        grantPermission(Manifest.permission.READ_CALENDAR);
+
+        // Read/write access should be allowed
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+        final Uri uri = insertCalendarItem();
+        try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+            assertEquals(1, c.getCount());
+        }
     }
 
     @Test
     public void testInteractiveGrant() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
         // Start out without permission
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+        try {
+            insertCalendarItem();
+            fail();
+        } catch (SecurityException expected) {
+        }
+        try (Cursor c = mContext.getContentResolver().query(
+                CalendarContract.Calendars.CONTENT_URI, null, null, null)) {
+            fail();
+        } catch (SecurityException expected) {
+        }
 
         // Go through normal grant flow
         BasePermissionActivity.Result result = requestPermissions(new String[] {
-                Manifest.permission.READ_EXTERNAL_STORAGE,
-                Manifest.permission.WRITE_EXTERNAL_STORAGE},
+                Manifest.permission.READ_CALENDAR,
+                Manifest.permission.WRITE_CALENDAR},
                 REQUEST_CODE_PERMISSIONS,
                 BasePermissionActivity.class,
                 () -> {
@@ -117,22 +115,20 @@
                 });
 
         assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
-        assertEquals(Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]);
-        assertEquals(Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]);
+        assertEquals(Manifest.permission.READ_CALENDAR, result.permissions[0]);
+        assertEquals(Manifest.permission.WRITE_CALENDAR, result.permissions[1]);
         assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
         assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
 
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
         // We should have permission now!
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+        final Uri uri = insertCalendarItem();
+        try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+            assertEquals(1, c.getCount());
+        }
     }
 
     @Test
@@ -680,4 +676,16 @@
             clickDenyAndDontAskAgainButton();
         }
     }
+
+    /**
+     * Attempt to insert a new unique calendar item; this might be ignored if
+     * this legacy app has its permission revoked.
+     */
+    private Uri insertCalendarItem() {
+        final ContentValues values = new ContentValues();
+        values.put(CalendarContract.Calendars.NAME, "cts" + System.nanoTime());
+        values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "cts");
+        values.put(CalendarContract.Calendars.CALENDAR_COLOR, 0xffff0000);
+        return mContext.getContentResolver().insert(CalendarContract.Calendars.CONTENT_URI, values);
+    }
 }
diff --git a/hostsidetests/backup/Android.mk b/hostsidetests/backup/Android.mk
index fd5b3c6..bbe7d47 100644
--- a/hostsidetests/backup/Android.mk
+++ b/hostsidetests/backup/Android.mk
@@ -25,7 +25,7 @@
 
 LOCAL_MODULE := CtsBackupHostTestCases
 
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util truth-prebuilt
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
diff --git a/tests/libcore/simplemmodule/Android.mk b/hostsidetests/backup/ProfileFullBackupApp/Android.mk
similarity index 73%
copy from tests/libcore/simplemmodule/Android.mk
copy to hostsidetests/backup/ProfileFullBackupApp/Android.mk
index 2e6adc1..1451e97 100644
--- a/tests/libcore/simplemmodule/Android.mk
+++ b/hostsidetests/backup/ProfileFullBackupApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,17 +16,8 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsLibcoreSimpleMModuleTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    cts-core-test-runner \
-    core-libart+oj-intra-test \
-    core-simple-intra-test
-
 # Don't include this package in any target
 LOCAL_MODULE_TAGS := tests
-
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
@@ -34,7 +25,18 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-# Tag this module as a cts test artifact
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    platform-test-annotations \
+    truth-prebuilt
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+LOCAL_PACKAGE_NAME := CtsProfileFullBackupApp
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml b/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml
new file mode 100644
index 0000000..36111b0
--- /dev/null
+++ b/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.cts.backup.profilefullbackupapp">
+
+    <application android:label="ProfileFullBackupApp">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.cts.backup.profilefullbackupapp" />
+
+</manifest>
diff --git a/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java b/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java
new file mode 100644
index 0000000..198a180
--- /dev/null
+++ b/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilefullbackupapp;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+/** Device side test invoked by ProfileFullBackupRestoreHostSideTest. */
+@RunWith(AndroidJUnit4.class)
+@AppModeFull
+public class ProfileFullBackupRestoreTest {
+    private static final String FILE_ONE_CONTENT = "file1text";
+    private static final String FILE_TWO_CONTENT = "file2text";
+
+    private File mFile1;
+    private File mFile2;
+
+    @Before
+    public void setUp() throws Exception {
+        File dir = getTargetContext().getFilesDir();
+        dir.mkdirs();
+
+        mFile1 = new File(dir, "file1");
+        mFile2 = new File(dir, "file2");
+    }
+
+    @Test
+    public void assertFilesDontExist() throws Exception {
+        assertThat(mFile1.exists()).isFalse();
+        assertThat(mFile2.exists()).isFalse();
+    }
+
+    @Test
+    public void writeFilesAndAssertSuccess() throws Exception {
+        Files.write(mFile1.toPath(), FILE_ONE_CONTENT.getBytes());
+        assertFileContains(mFile1, FILE_ONE_CONTENT);
+
+        Files.write(mFile2.toPath(), FILE_TWO_CONTENT.getBytes());
+        assertFileContains(mFile2, FILE_TWO_CONTENT);
+    }
+
+    @Test
+    public void clearFilesAndAssertSuccess() throws Exception {
+        mFile1.delete();
+        mFile2.delete();
+        assertFilesDontExist();
+    }
+
+    @Test
+    public void assertFilesRestored() throws Exception {
+        assertThat(mFile1.exists()).isTrue();
+        assertFileContains(mFile1, FILE_ONE_CONTENT);
+
+        assertThat(mFile2.exists()).isTrue();
+        assertFileContains(mFile2, FILE_TWO_CONTENT);
+    }
+
+    private void assertFileContains(File file, String content) throws IOException {
+        assertThat(Files.readAllBytes(file.toPath())).isEqualTo(content.getBytes());
+    }
+}
diff --git a/tests/libcore/simplemmodule/Android.mk b/hostsidetests/backup/ProfileKeyValueApp/Android.mk
similarity index 73%
rename from tests/libcore/simplemmodule/Android.mk
rename to hostsidetests/backup/ProfileKeyValueApp/Android.mk
index 2e6adc1..89213f2 100644
--- a/tests/libcore/simplemmodule/Android.mk
+++ b/hostsidetests/backup/ProfileKeyValueApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,17 +16,8 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsLibcoreSimpleMModuleTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    cts-core-test-runner \
-    core-libart+oj-intra-test \
-    core-simple-intra-test
-
 # Don't include this package in any target
 LOCAL_MODULE_TAGS := tests
-
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
@@ -34,7 +25,18 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-# Tag this module as a cts test artifact
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    platform-test-annotations \
+    truth-prebuilt
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+LOCAL_PACKAGE_NAME := CtsProfileKeyValueApp
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml b/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml
new file mode 100644
index 0000000..fbc8602
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.cts.backup.profilekeyvalueapp">
+
+    <application
+        android:backupAgent=".ProfileKeyValueBackupAgent"
+        android:killAfterRestore="false" >
+
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.cts.backup.profilekeyvalueapp" />
+
+</manifest>
diff --git a/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java
new file mode 100644
index 0000000..d4cd3a7
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilekeyvalueapp;
+
+import android.app.backup.BackupAgentHelper;
+import android.app.backup.SharedPreferencesBackupHelper;
+
+/**
+ * Backup agent that uses {@link SharedPreferencesBackupHelper} to backup/restore shared
+ * preferences.
+ */
+public class ProfileKeyValueBackupAgent extends BackupAgentHelper {
+    private static final String PREFS_PREFIX = "USER-KV";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        SharedPreferencesBackupHelper backupHelper =
+                new SharedPreferencesBackupHelper(
+                        this, ProfileKeyValueBackupRestoreTest.TEST_PREFS_NAME);
+        addHelper(PREFS_PREFIX, backupHelper);
+    }
+}
diff --git a/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java
new file mode 100644
index 0000000..0081d15
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilekeyvalueapp;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Device side test invoked by ProfileKeyValueBackupRestoreHostSideTest. */
+@RunWith(AndroidJUnit4.class)
+@AppModeFull
+public class ProfileKeyValueBackupRestoreTest {
+    static final String TEST_PREFS_NAME = "user-test-prefs";
+    private static final String PREFS_USER_KEY = "userId";
+    private static final int PREFS_USER_DEFAULT = -1000;
+
+    private int mUserId;
+    private SharedPreferences mPreferences;
+
+    @Before
+    public void setUp() {
+        Context context = getTargetContext();
+        mUserId = context.getUserId();
+        mPreferences = context.getSharedPreferences(TEST_PREFS_NAME, Context.MODE_PRIVATE);
+    }
+
+    @Test
+    public void assertSharedPrefsIsEmpty() {
+        int userIdPref = mPreferences.getInt(PREFS_USER_KEY, PREFS_USER_DEFAULT);
+        assertThat(userIdPref).isEqualTo(PREFS_USER_DEFAULT);
+    }
+
+    @Test
+    public void writeSharedPrefsAndAssertSuccess() {
+        SharedPreferences.Editor editor = mPreferences.edit();
+        editor.putInt(PREFS_USER_KEY, mUserId);
+        assertThat(editor.commit()).isTrue();
+    }
+
+    @Test
+    public void assertSharedPrefsRestored() {
+        int userIdPref = mPreferences.getInt(PREFS_USER_KEY, PREFS_USER_DEFAULT);
+        assertThat(userIdPref).isEqualTo(mUserId);
+    }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
new file mode 100644
index 0000000..089faca
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/** Base class for CTS multi-user backup/restore host-side tests. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public abstract class BaseMultiUserBackupHostSideTest extends BaseBackupHostSideTest {
+    private static final String USER_SETUP_COMPLETE_SETTING = "user_setup_complete";
+    private static final int BROADCAST_IDLE_TIMEOUT_MIN = 2;
+
+    private final BackupUtils mBackupUtils = getBackupUtils();
+    private ITestDevice mDevice;
+
+    // Store initial device state as Optional as tearDown() will execute even if we have assumption
+    // failures in setUp().
+    private Optional<Integer> mInitialUser = Optional.empty();
+
+    /** Check device features and keep track of pre-test device state. */
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+
+        // Check that backup and multi-user features are both supported.
+        assumeTrue("Backup feature not supported", mIsBackupSupported);
+        assumeTrue("Multi-user feature not supported", mDevice.isMultiUserSupported());
+
+        // Keep track of initial user state to restore in tearDown.
+        int currentUserId = mDevice.getCurrentUser();
+        mInitialUser = Optional.of(currentUserId);
+
+        // Switch to primary user.
+        int primaryUserId = mDevice.getPrimaryUserId();
+        if (currentUserId != primaryUserId) {
+            mDevice.switchUser(primaryUserId);
+        }
+    }
+
+    /** Restore pre-test device state. */
+    @After
+    public void tearDown() throws Exception {
+        if (mInitialUser.isPresent()) {
+            mDevice.switchUser(mInitialUser.get());
+            mInitialUser = Optional.empty();
+        }
+    }
+
+    /**
+     * Attempts to create a profile tied to the parent user {@code parentId}. Returns the user id of
+     * the profile if successful, otherwise throws a {@link RuntimeException}.
+     */
+    int createProfileUser(int parentId, String profileName) throws IOException {
+        String output =
+                mBackupUtils.executeShellCommandAndReturnOutput(
+                        String.format("pm create-user --profileOf %d %s", parentId, profileName));
+        try {
+            // Expected output is "Success: created user id <id>"
+            String userId = output.substring(output.lastIndexOf(" ")).trim();
+            return Integer.parseInt(userId);
+        } catch (NumberFormatException e) {
+            CLog.d("Failed to parse user id when creating a profile user");
+            throw new RuntimeException();
+        }
+    }
+
+    /** Start the user and set necessary conditions for backup to be enabled in the user. */
+    void startUserAndInitializeForBackup(int userId) throws Exception {
+        // Turn on multi-user feature for this user.
+        mBackupUtils.executeShellCommandSync(
+                String.format("bmgr --user %d activate %b", userId, true));
+
+        mDevice.startUser(userId);
+        // Wait for user to be fully started.
+        mDevice.executeShellV2Command(
+                "am wait-for-broadcast-idle", BROADCAST_IDLE_TIMEOUT_MIN, TimeUnit.MINUTES);
+
+        mDevice.setSetting(userId, "secure", USER_SETUP_COMPLETE_SETTING, "1");
+        mBackupUtils.enableBackupForUser(true, userId);
+        assertThat(mBackupUtils.isBackupEnabledForUser(userId)).isTrue();
+    }
+
+    /**
+     * Selects the local transport as the current transport for user {@code userId}. Returns the
+     * {@link String} name of the local transport.
+     */
+    String switchUserToLocalTransportAndAssertSuccess(int userId) throws IOException {
+        // Make sure the user has the local transport.
+        String localTransport = mBackupUtils.getLocalTransportName();
+        assertThat(mBackupUtils.userHasBackupTransport(localTransport, userId)).isTrue();
+
+        // Switch to the local transport and assert success.
+        mBackupUtils.setBackupTransportForUser(localTransport, userId);
+        assertThat(mBackupUtils.isLocalTransportSelectedForUser(userId)).isTrue();
+
+        return localTransport;
+    }
+
+    /** Runs "bmgr --user <id> wipe <transport> <package>" to clear the backup data. */
+    void clearBackupDataInTransportForUser(String packageName, String transport, int userId)
+            throws DeviceNotAvailableException {
+        mDevice.executeShellCommand(
+                String.format("bmgr --user %d wipe %s %s", userId, transport, packageName));
+    }
+
+    /** Clears data of {@code packageName} for user {@code userId}. */
+    void clearPackageDataAsUser(String packageName, int userId) throws DeviceNotAvailableException {
+        mDevice.executeShellCommand(String.format("pm clear --user %d %s", userId, packageName));
+    }
+
+    /** Uninstalls {@code packageName} for user {@code userId}. */
+    void uninstallPackageAsUser(String packageName, int userId) throws DeviceNotAvailableException {
+        mDevice.executeShellCommand(
+                String.format("pm uninstall --user %d %s", userId, packageName));
+    }
+
+    /** Run device side test as user {@code userId}. */
+    void checkDeviceTestAsUser(String packageName, String className, String testName, int userId)
+            throws DeviceNotAvailableException {
+        boolean result = runDeviceTests(mDevice, packageName, className, testName, userId, null);
+        assertThat(result).isTrue();
+    }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java
new file mode 100644
index 0000000..56e2892
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test the backup and restore flow for a full-backup app in a profile. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public class ProfileFullBackupRestoreHostSideTest extends BaseMultiUserBackupHostSideTest {
+    private static final String TEST_APK = "CtsProfileFullBackupApp.apk";
+    private static final String TEST_FULL_BACKUP_PACKAGE =
+            "android.cts.backup.profilefullbackupapp";
+    private static final String DEVICE_TEST_NAME =
+            TEST_FULL_BACKUP_PACKAGE + ".ProfileFullBackupRestoreTest";
+
+    private final BackupUtils mBackupUtils = getBackupUtils();
+    private ITestDevice mDevice;
+    private int mProfileUserId;
+    private String mTransport;
+
+    /** Create the profile, switch to the local transport and setup the test package. */
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+
+        // Create profile user.
+        int parentUserId = mDevice.getCurrentUser();
+        mProfileUserId = createProfileUser(parentUserId, "Profile-Full");
+        startUserAndInitializeForBackup(mProfileUserId);
+
+        // Switch to local transport.
+        mTransport = switchUserToLocalTransportAndAssertSuccess(mProfileUserId);
+
+        // Setup test package.
+        installPackageAsUser(TEST_APK, true, mProfileUserId);
+        clearPackageDataAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+    }
+
+    /** Uninstall the test package and remove the profile. */
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        clearBackupDataInTransportForUser(TEST_FULL_BACKUP_PACKAGE, mTransport, mProfileUserId);
+        uninstallPackageAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+        mDevice.removeUser(mProfileUserId);
+        super.tearDown();
+    }
+
+    /**
+     * Tests full-backup app backup and restore in the profile user using system restore.
+     *
+     * <ol>
+     *   <li>App writes files to its directory.
+     *   <li>Force a backup.
+     *   <li>Clear the app's files.
+     *   <li>Force a restore.
+     *   <li>Check that the files and its contents are restored.
+     * </ol>
+     */
+    @Test
+    public void testFullBackupAndSystemRestore() throws Exception {
+        checkDeviceTest("assertFilesDontExist");
+        checkDeviceTest("writeFilesAndAssertSuccess");
+
+        mBackupUtils.backupNowAndAssertSuccessForUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+        checkDeviceTest("clearFilesAndAssertSuccess");
+
+        mBackupUtils.restoreAndAssertSuccessForUser(
+                BackupUtils.LOCAL_TRANSPORT_TOKEN, TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+        checkDeviceTest("assertFilesRestored");
+    }
+
+    /**
+     * Tests full-backup app backup and restore in the profile user using restore at install.
+     *
+     * <ol>
+     *   <li>App writes files to its directory.
+     *   <li>Force a backup.
+     *   <li>Uninstall the app.
+     *   <li>Install the app to perform a restore-at-install operation.
+     *   <li>Check that the files and its contents are restored.
+     * </ol>
+     */
+    @Test
+    public void testFullBackupAndRestoreAtInstall() throws Exception {
+        checkDeviceTest("assertFilesDontExist");
+        checkDeviceTest("writeFilesAndAssertSuccess");
+
+        mBackupUtils.backupNowAndAssertSuccessForUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+        checkDeviceTest("clearFilesAndAssertSuccess");
+
+        uninstallPackageAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+        installPackageAsUser(TEST_APK, true, mProfileUserId);
+
+        checkDeviceTest("assertFilesRestored");
+    }
+
+    private void checkDeviceTest(String methodName) throws DeviceNotAvailableException {
+        checkDeviceTestAsUser(
+                TEST_FULL_BACKUP_PACKAGE, DEVICE_TEST_NAME, methodName, mProfileUserId);
+    }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java
new file mode 100644
index 0000000..2ee45c4
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test the backup and restore flow for a key-value app in a profile. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public class ProfileKeyValueBackupRestoreHostSideTest extends BaseMultiUserBackupHostSideTest {
+    private static final String TEST_APK = "CtsProfileKeyValueApp.apk";
+    private static final String TEST_PACKAGE = "android.cts.backup.profilekeyvalueapp";
+    private static final String DEVICE_TEST_NAME =
+            TEST_PACKAGE + ".ProfileKeyValueBackupRestoreTest";
+
+    private final BackupUtils mBackupUtils = getBackupUtils();
+    private ITestDevice mDevice;
+    private int mProfileUserId;
+    private String mTransport;
+
+    /** Create the profile, switch to the local transport and setup the test package. */
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+
+        // Create profile user.
+        int parentUserId = mDevice.getCurrentUser();
+        mProfileUserId = createProfileUser(parentUserId, "Profile-KV");
+        startUserAndInitializeForBackup(mProfileUserId);
+
+        // Switch to local transport.
+        mTransport = switchUserToLocalTransportAndAssertSuccess(mProfileUserId);
+
+        // Setup test package.
+        installPackageAsUser(TEST_APK, true, mProfileUserId);
+        clearPackageDataAsUser(TEST_PACKAGE, mProfileUserId);
+    }
+
+    /** Uninstall the test package and remove the profile. */
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        clearBackupDataInTransportForUser(TEST_PACKAGE, mTransport, mProfileUserId);
+        uninstallPackageAsUser(TEST_PACKAGE, mProfileUserId);
+        mDevice.removeUser(mProfileUserId);
+        super.tearDown();
+    }
+
+    /**
+     * Tests key-value app backup and restore in the profile user.
+     *
+     * <ol>
+     *   <li>App writes shared preferences.
+     *   <li>Force a backup.
+     *   <li>Uninstall the app.
+     *   <li>Install the app to perform a restore-at-install operation.
+     *   <li>Check that the shared preferences are restored.
+     * </ol>
+     */
+    @Test
+    public void testKeyValueBackupAndRestore() throws Exception {
+        checkDeviceTest("assertSharedPrefsIsEmpty");
+        checkDeviceTest("writeSharedPrefsAndAssertSuccess");
+
+        mBackupUtils.backupNowAndAssertSuccessForUser(TEST_PACKAGE, mProfileUserId);
+
+        uninstallPackageAsUser(TEST_PACKAGE, mProfileUserId);
+
+        installPackageAsUser(TEST_APK, true, mProfileUserId);
+
+        checkDeviceTest("assertSharedPrefsRestored");
+    }
+
+    private void checkDeviceTest(String methodName) throws DeviceNotAvailableException {
+        checkDeviceTestAsUser(TEST_PACKAGE, DEVICE_TEST_NAME, methodName, mProfileUserId);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
index fffee81..e16aa42 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
@@ -31,7 +31,9 @@
 
     // Test that a key generation request succeeds when device identifiers are requested.
     public void testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess() {
-        KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDpm, null);
+        if (mDpm.isDeviceIdAttestationSupported()) {
+            KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDpm, null);
+        }
     }
 
     // Test that a key generation request fails when device identifiers are requested.
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
index 22eab0b..4c10faa 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
@@ -18,6 +18,7 @@
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.test.AndroidTestCase;
 
@@ -28,6 +29,7 @@
 
     protected String mPackageName;
     protected ComponentName mAdminComponent;
+    protected boolean mHasSecureLockScreen;
 
     public DevicePolicyManager dpm;
 
@@ -38,6 +40,8 @@
         dpm = mContext.getSystemService(DevicePolicyManager.class);
         mPackageName = mContext.getPackageName();
         mAdminComponent = new ComponentName(mContext, AdminReceiver.class);
+        mHasSecureLockScreen = mContext.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
     }
 
     /**
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
index 90f24cb..2394a9a 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
@@ -41,6 +41,9 @@
     }
 
     public void testGetMaximumFailedPasswordsForWipe() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         dpm.setMaximumFailedPasswordsForWipe(mAdminComponent, 3);
         assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(mAdminComponent));
 
@@ -49,6 +52,9 @@
     }
 
     public void testPasswordHistoryLength() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         // Password history length restriction is only imposed if password quality is at least
         // numeric.
         dpm.setPasswordQuality(mAdminComponent,
@@ -66,6 +72,9 @@
     }
 
     public void testPasswordExpirationTimeout() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         long originalValue = dpm.getPasswordExpirationTimeout(mAdminComponent);
         try {
             for (long testLength : new long[] {
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
index 3a123d9..402ca9f 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
@@ -42,6 +42,9 @@
 
     @Override
     public void testPasswordHistoryLength() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         int originalValue = dpm.getPasswordHistoryLength(mAdminComponent);
         assertSecurityException(() -> dpm.setPasswordHistoryLength(mAdminComponent, 3));
         assertEquals(originalValue, dpm.getPasswordHistoryLength(mAdminComponent));
@@ -98,6 +101,9 @@
 
     @Override
     public void testPasswordExpirationTimeout() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         long originalValue = dpm.getPasswordExpirationTimeout(mAdminComponent);
         assertSecurityException(() -> dpm.setPasswordExpirationTimeout(mAdminComponent, 1234L));
         assertEquals(originalValue, dpm.getPasswordExpirationTimeout(mAdminComponent));
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index 0fc8f48..bc33910 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -20,7 +20,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -249,7 +248,6 @@
                 mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT));
 
         // Exercise installKeyPair()
-        checkKeyguardPrecondition();
         installKeyPair(TEST_KEY, TEST_CERT, alias);
         assertResult("installKeyPair", true);
     }
@@ -315,19 +313,6 @@
         assertThat(mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT)).isNull();
     }
 
-    /**
-     * installKeyPair() requires the system to have a lockscreen password, which should have been
-     * set by the host side test.
-     */
-    private void checkKeyguardPrecondition() throws InterruptedException {
-        KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        if (!km.isKeyguardSecure()) {
-            Thread.sleep(5000);
-          }
-          assertTrue("A lockscreen password is required before keypair can be installed",
-                          km.isKeyguardSecure());
-    }
-
     private void installCaCert(byte[] cert) {
         Intent intent = new Intent();
         intent.setAction(ACTION_INSTALL_CERT);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
index 196000f..bce0a08 100755
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
@@ -35,8 +35,10 @@
     // Test that the same key generation request succeeds once the profile owner was granted
     // access to device identifiers.
     public void testSucceedsWithProfileOwnerIdsGrant() {
-        KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDevicePolicyManager,
-                getWho());
+        if (mDevicePolicyManager.isDeviceIdAttestationSupported()) {
+            KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(
+                    mDevicePolicyManager, getWho());
+        }
     }
 
     protected ComponentName getWho() {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index 9175d9b..9562a1f6 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -18,6 +18,7 @@
 import android.app.Instrumentation;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
+import android.content.pm.PackageManager;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
 import android.test.AndroidTestCase;
@@ -35,6 +36,8 @@
     protected DevicePolicyManager mDevicePolicyManager;
     protected Instrumentation mInstrumentation;
     protected UiDevice mDevice;
+    protected boolean mHasSecureLockScreen;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -42,6 +45,8 @@
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mDevice = UiDevice.getInstance(mInstrumentation);
         mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+        mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SECURE_LOCK_SCREEN);
         assertDeviceOwner();
     }
 
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
index 6d38843..c6c62ee 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
@@ -17,7 +17,13 @@
 package com.android.cts.deviceowner;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.SystemClock;
+
+import com.android.compatibility.common.util.SystemUtil;
 
 import java.io.File;
 import java.util.concurrent.CountDownLatch;
@@ -27,6 +33,11 @@
  * Test {@link android.app.admin.DevicePolicyManager#installSystemUpdate}
  */
 public class InstallUpdateTest extends BaseDeviceOwnerTest {
+    private static final int BATTERY_STATE_CHANGE_TIMEOUT_MS = 5000;
+    private static final int BATTERY_STATE_CHANGE_SLEEP_PER_CHECK_MS = 50;
+    private static final int TEST_BATTERY_THRESHOLD = 10;
+    private static final IntentFilter BATTERY_CHANGED_FILTER =
+            new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
 
     public static final String TEST_SYSTEM_UPDATES_DIR =
             "/data/local/tmp/cts/deviceowner/";
@@ -36,7 +47,6 @@
         assertUpdateError(
                 "random",
                 DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND);
-
     }
 
     public void testInstallUpdate_failWrongVersion() throws InterruptedException {
@@ -70,6 +80,58 @@
                 DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
     }
 
+    public void testInstallUpdate_notCharging_belowThreshold_failsBatteryCheck() throws Exception {
+        try {
+            setNonChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+            setNonChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD - 1);
+            assertUpdateError("wrongSize.zip",
+                    DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_BATTERY_LOW);
+        } finally {
+            resetBatteryState();
+            resetDevicePolicyConstants();
+        }
+    }
+
+    public void testInstallUpdate_notCharging_aboveThreshold_passesBatteryCheck() throws Exception {
+        try {
+            setNonChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+            setNonChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+            // Positive CTS tests aren't possible, so we verify that we get the file-related error
+            // rather than the battery one.
+            assertUpdateError("wrongSize.zip",
+                    DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            resetBatteryState();
+            resetDevicePolicyConstants();
+        }
+    }
+
+    public void testInstallUpdate_charging_belowThreshold_failsBatteryCheck() throws Exception {
+        try {
+            setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+            setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD - 1);
+            assertUpdateError("wrongSize.zip",
+                    DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_BATTERY_LOW);
+        } finally {
+            resetBatteryState();
+            resetDevicePolicyConstants();
+        }
+    }
+
+    public void testInstallUpdate_charging_aboveThreshold_passesBatteryCheck() throws Exception {
+        try {
+            setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+            setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+            // Positive CTS tests aren't possible, so we verify that we get the file-related error
+            // rather than the battery one.
+            assertUpdateError("wrongSize.zip",
+                    DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            resetBatteryState();
+            resetDevicePolicyConstants();
+        }
+    }
+
     private void assertUpdateError(String fileName, int expectedErrorCode)
             throws InterruptedException {
         CountDownLatch latch = new CountDownLatch(1);
@@ -87,4 +149,60 @@
                 });
         assertTrue(latch.await(TIMEOUT, TimeUnit.MINUTES));
     }
-}
\ No newline at end of file
+
+    private void setNonChargingBatteryThreshold(int threshold) {
+        SystemUtil.runShellCommand(
+                "settings put global device_policy_constants battery_threshold_not_charging="
+                        + threshold);
+    }
+
+    private void setNonChargingBatteryLevelAndWait(int level) throws Exception {
+        setBatteryStateAndWait(/* plugged= */ false, level);
+    }
+
+    private void setChargingBatteryThreshold(int threshold) {
+        SystemUtil.runShellCommand(
+                "settings put global device_policy_constants battery_threshold_charging="
+                        + threshold);
+    }
+
+    private void setChargingBatteryLevelAndWait(int level) throws Exception {
+        setBatteryStateAndWait(/* plugged= */ true, level);
+    }
+
+    /** Should be paired with {@link #resetBatteryState()} in a {@code finally} block. */
+    private void setBatteryStateAndWait(boolean plugged, int level) throws Exception {
+        SystemUtil.runShellCommand(plugged ? "cmd battery set ac 1" : "cmd battery unplug");
+        SystemUtil.runShellCommand("cmd battery set -f level " + level);
+        long startTime = SystemClock.elapsedRealtime();
+        while (!isBatteryState(plugged, level)
+                && SystemClock.elapsedRealtime() <= startTime + BATTERY_STATE_CHANGE_TIMEOUT_MS) {
+            Thread.sleep(BATTERY_STATE_CHANGE_SLEEP_PER_CHECK_MS);
+        }
+    }
+
+    private boolean isBatteryState(boolean plugged, int level) {
+        final Intent batteryStatus =
+                mContext.registerReceiver(/* receiver= */ null, BATTERY_CHANGED_FILTER);
+        return isPluggedIn(batteryStatus) == plugged
+                && calculateBatteryPercentage(batteryStatus) == level;
+    }
+
+    private boolean isPluggedIn(Intent batteryStatus) {
+        return batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, /* defaultValue= */ -1) > 0;
+    }
+
+    private float calculateBatteryPercentage(Intent batteryStatus) {
+        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, /* defaultValue= */ -1);
+        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, /* defaultValue= */ -1);
+        return 100 * level / (float) scale;
+    }
+
+    private void resetBatteryState() {
+        SystemUtil.runShellCommand("dumpsys battery reset");
+    }
+
+    private void resetDevicePolicyConstants() {
+        SystemUtil.runShellCommand("settings delete global device_policy_constants");
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
index 5118b83..4d4e306 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -253,9 +253,11 @@
     }
 
     private void verifyAdminEventsPresent(List<SecurityEvent> events) {
-        verifyPasswordComplexityEventsPresent(events);
-        verifyUserRestrictionEventsPresent(events);
+        if (mHasSecureLockScreen) {
+            verifyPasswordComplexityEventsPresent(events);
+        }
         verifyLockingPolicyEventsPresent(events);
+        verifyUserRestrictionEventsPresent(events);
     }
 
     /**
@@ -280,9 +282,11 @@
     }
 
     private void generateAdminEvents() {
-        generatePasswordComplexityEvents();
-        generateUserRestrictionEvents();
+        if (mHasSecureLockScreen) {
+            generatePasswordComplexityEvents();
+        }
         generateLockingPolicyEvents();
+        generateUserRestrictionEvents();
     }
 
     /**
@@ -606,9 +610,12 @@
     }
 
     private void generateLockingPolicyEvents() {
-        mDevicePolicyManager.setPasswordExpirationTimeout(getWho(), TEST_PWD_EXPIRATION_TIMEOUT);
-        mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
-        mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+        if (mHasSecureLockScreen) {
+            mDevicePolicyManager.setPasswordExpirationTimeout(getWho(),
+                    TEST_PWD_EXPIRATION_TIMEOUT);
+            mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
+            mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+        }
         mDevicePolicyManager.setKeyguardDisabledFeatures(getWho(), KEYGUARD_DISABLE_FINGERPRINT);
         mDevicePolicyManager.setMaximumTimeToLock(getWho(), TEST_MAX_TIME_TO_LOCK);
         mDevicePolicyManager.lockNow();
@@ -617,26 +624,28 @@
     private void verifyLockingPolicyEventsPresent(List<SecurityEvent> events) {
         final int userId = Process.myUserHandle().getIdentifier();
 
-        findEvent("set password expiration", events,
-                e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
-                        getInt(e, ADMIN_USER_INDEX) == userId &&
-                        getInt(e, TARGET_USER_INDEX) == userId &&
-                        getLong(e, PWD_EXPIRATION_INDEX) == TEST_PWD_EXPIRATION_TIMEOUT);
+        if (mHasSecureLockScreen) {
+            findEvent("set password expiration", events,
+                    e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
+                            getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                            getInt(e, ADMIN_USER_INDEX) == userId &&
+                            getInt(e, TARGET_USER_INDEX) == userId &&
+                            getLong(e, PWD_EXPIRATION_INDEX) == TEST_PWD_EXPIRATION_TIMEOUT);
 
-        findEvent("set password history length", events,
-                e -> e.getTag() == TAG_PASSWORD_HISTORY_LENGTH_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
-                        getInt(e, ADMIN_USER_INDEX) == userId &&
-                        getInt(e, TARGET_USER_INDEX) == userId &&
-                        getInt(e, PWD_HIST_LEN_INDEX) == TEST_PWD_HISTORY_LENGTH);
+            findEvent("set password history length", events,
+                    e -> e.getTag() == TAG_PASSWORD_HISTORY_LENGTH_SET &&
+                            getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                            getInt(e, ADMIN_USER_INDEX) == userId &&
+                            getInt(e, TARGET_USER_INDEX) == userId &&
+                            getInt(e, PWD_HIST_LEN_INDEX) == TEST_PWD_HISTORY_LENGTH);
 
-        findEvent("set password attempts", events,
-                e -> e.getTag() == TAG_MAX_PASSWORD_ATTEMPTS_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
-                        getInt(e, ADMIN_USER_INDEX) == userId &&
-                        getInt(e, TARGET_USER_INDEX) == userId &&
-                        getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
+            findEvent("set password attempts", events,
+                    e -> e.getTag() == TAG_MAX_PASSWORD_ATTEMPTS_SET &&
+                            getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                            getInt(e, ADMIN_USER_INDEX) == userId &&
+                            getInt(e, TARGET_USER_INDEX) == userId &&
+                            getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
+        }
 
         findEvent("set keyguard disabled features", events,
                 e -> e.getTag() == TAG_KEYGUARD_DISABLED_FEATURES_SET &&
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
index f10822c..ae530f3 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
@@ -19,6 +19,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.test.InstrumentationTestCase;
 
 /**
@@ -38,6 +39,7 @@
     protected DevicePolicyManager mDevicePolicyManager;
     protected DevicePolicyManager mParentDevicePolicyManager;
     protected Context mContext;
+    protected boolean mHasSecureLockScreen;
 
     @Override
     protected void setUp() throws Exception {
@@ -54,6 +56,9 @@
         assertTrue(mDevicePolicyManager.isProfileOwnerApp(
                 ADMIN_RECEIVER_COMPONENT.getPackageName()));
         assertTrue(mDevicePolicyManager.isManagedProfile(ADMIN_RECEIVER_COMPONENT));
+
+        mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SECURE_LOCK_SCREEN);
     }
 
     protected DevicePolicyManager getDevicePolicyManager(boolean isParent) {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
index 879076a..522f048 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
@@ -41,7 +41,12 @@
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.text.format.Time;
+import android.util.ArraySet;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -132,15 +137,15 @@
                 ADMIN_RECEIVER_COMPONENT);
         assertThat(whitelist).isEmpty();
 
-        mDevicePolicyManager.addCrossProfileCalendarPackage(
-                ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG);
+        mDevicePolicyManager.setCrossProfileCalendarPackages(
+                ADMIN_RECEIVER_COMPONENT, new ArraySet<String>(Arrays.asList(MANAGED_PROFILE_PKG)));
         whitelist = mDevicePolicyManager.getCrossProfileCalendarPackages(
                 ADMIN_RECEIVER_COMPONENT);
         assertThat(whitelist.size()).isEqualTo(1);
         assertThat(whitelist.contains(MANAGED_PROFILE_PKG)).isTrue();
 
-        assertThat(mDevicePolicyManager.removeCrossProfileCalendarPackage(
-                ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG)).isTrue();
+        mDevicePolicyManager.setCrossProfileCalendarPackages(
+                ADMIN_RECEIVER_COMPONENT, Collections.emptySet());
         whitelist = mDevicePolicyManager.getCrossProfileCalendarPackages(
                 ADMIN_RECEIVER_COMPONENT);
         assertThat(whitelist).isEmpty();
@@ -392,15 +397,22 @@
     // Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
     public void testWhitelistManagedProfilePackage() {
         requireRunningOnManagedProfile();
-        mDevicePolicyManager.addCrossProfileCalendarPackage(
-                ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG);
+        mDevicePolicyManager.setCrossProfileCalendarPackages(
+                ADMIN_RECEIVER_COMPONENT, new ArraySet<String>(Arrays.asList(MANAGED_PROFILE_PKG)));
     }
 
     // Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
-    public void testRemoveManagedProfilePackageFromWhitelist() {
+    public void testWhitelistAllPackages() {
         requireRunningOnManagedProfile();
-        assertThat(mDevicePolicyManager.removeCrossProfileCalendarPackage(
-                ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG)).isTrue();
+        mDevicePolicyManager.setCrossProfileCalendarPackages(
+                ADMIN_RECEIVER_COMPONENT, null);
+    }
+
+    // Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
+    public void testCleanupWhitelist() {
+        requireRunningOnManagedProfile();
+        mDevicePolicyManager.setCrossProfileCalendarPackages(
+                ADMIN_RECEIVER_COMPONENT, Collections.emptySet());
     }
 
     // Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
index 9bd721f..c7f905a 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
@@ -31,6 +31,9 @@
     }
 
     public void testSetAndGetPasswordHistoryLength_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final int passwordHistoryLength = 5;
 
         mParentDevicePolicyManager.setPasswordHistoryLength(
@@ -42,6 +45,9 @@
     }
 
     public void testSetAndGetPasswordExpirationTimeout_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final int passwordExpirationTimeout = 432000000;
 
         mParentDevicePolicyManager.setPasswordExpirationTimeout(
@@ -53,6 +59,9 @@
     }
 
     public void testGetPasswordExpiration_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final long passwordExpirationTimeout = 432000000;
         final long currentTime = System.currentTimeMillis();
 
@@ -85,6 +94,9 @@
     }
 
     public void testSetAndGetMaximumFailedPasswordsForWipe_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final int maximumFailedPasswordsForWipe = 15;
 
         mParentDevicePolicyManager.setMaximumFailedPasswordsForWipe(
@@ -122,6 +134,9 @@
     }
 
     public void testSetAndGetTrustAgentConfiguration_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final PersistableBundle configuration = new PersistableBundle();
         final String key = "key";
         final String value = "value";
@@ -137,6 +152,9 @@
     }
 
     public void testSetAndGetRequiredStrongAuthTimeout_onParent() {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         final int requiredStrongAuthTimeout = 4600000;
 
         mParentDevicePolicyManager.setRequiredStrongAuthTimeout(
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
index 3f44008..9f65303 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
@@ -44,7 +44,7 @@
         } else if (ACTION_WIPE_DATA_WITH_REASON.equals(intent.getAction())) {
             dpm.wipeData(0, TEST_WIPE_DATA_REASON);
         } else if (ACTION_WIPE_DATA_WITHOUT_REASON.equals(intent.getAction())) {
-            dpm.wipeData(0, null);
+            dpm.wipeData(DevicePolicyManager.WIPE_SILENTLY);
         }
     }
 }
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
index 5d255e0e..7822e1a 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
@@ -25,6 +25,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.SharedPreferences;
 import android.os.IBinder;
 import android.os.PersistableBundle;
@@ -73,12 +74,15 @@
     protected Context mContext;
     protected ComponentName mIncomingComponentName;
     protected DevicePolicyManager mDevicePolicyManager;
+    protected boolean mHasSecureLockScreen;
 
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
         mIncomingComponentName = new ComponentName(mContext, BasicAdminReceiver.class.getName());
+        mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SECURE_LOCK_SCREEN);
     }
 
     @Test
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
index ef7e8ac..1d91237 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
@@ -40,8 +40,10 @@
 
         DevicePolicyManager targetParentProfileInstance =
                 mDevicePolicyManager.getParentProfileInstance(mIncomingComponentName);
-        assertEquals(
-                passwordExpirationTimeout,
-                targetParentProfileInstance.getPasswordExpirationTimeout(mIncomingComponentName));
+        if (mHasSecureLockScreen) {
+            assertEquals(
+                    passwordExpirationTimeout,
+                    targetParentProfileInstance.getPasswordExpirationTimeout(mIncomingComponentName));
+        }
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
index 4425dcd..8141b11 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
@@ -91,7 +91,7 @@
     }
 
     public void testResetPassword_nycRestrictions() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
 
@@ -111,7 +111,7 @@
      * Run the tests in DeviceOwnerPasswordTest.java (as device owner).
      */
     public void testRunDeviceOwnerPasswordTest() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 930e66d..53e45fc 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -133,6 +133,9 @@
     /** Whether file-based encryption (FBE) is supported. */
     protected boolean mSupportsFbe;
 
+    /** Whether the device has a lock screen.*/
+    protected boolean mHasSecureLockScreen;
+
     /** Users we shouldn't delete in the tests */
     private ArrayList<Integer> mFixedUsers;
 
@@ -156,6 +159,8 @@
         mFixedPackages = getDevice().getInstalledPackageNames();
         mBuildHelper = new CompatibilityBuildHelper(mCtsBuild);
 
+        mHasSecureLockScreen = hasDeviceFeature("android.software.secure_lock_screen");
+
         // disable the package verifier to avoid the dialog when installing an app
         mPackageVerifier = getDevice().executeShellCommand(
                 "settings get global package_verifier_enable");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index bf94abb..c9c31f8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -342,9 +342,6 @@
             return;
         }
 
-        // Set a device lockscreen password (precondition for installing private key pairs).
-        changeUserCredential("1234", null, mPrimaryUserId);
-
         // Install relevant apps.
         installAppAsUser(DELEGATE_APP_APK, mUserId);
         installAppAsUser(TEST_APP_APK, mUserId);
@@ -370,8 +367,6 @@
             executeDeviceTestClass(".DelegationTest");
 
         } finally {
-            // Clear lockscreen password previously set for installing private key pairs.
-            changeUserCredential(null, "1234", mPrimaryUserId);
             // Remove any remaining delegations.
             setDelegatedScopes(DELEGATE_APP_PKG, null);
         }
@@ -381,17 +376,11 @@
         if (!mHasFeature) {
             return;
         }
-        changeUserCredential("1234", null, mUserId);
 
-        try {
-            installAppAsUser(CERT_INSTALLER_APK, mUserId);
-            setDelegatedScopes(CERT_INSTALLER_PKG, Arrays.asList(
-                    DELEGATION_CERT_INSTALL, DELEGATION_CERT_SELECTION));
-            runDeviceTestsAsUser(CERT_INSTALLER_PKG, ".CertSelectionDelegateTest", mUserId);
-            // Uninstall of test packages happen in tearDown.
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
+        installAppAsUser(CERT_INSTALLER_APK, mUserId);
+        setDelegatedScopes(CERT_INSTALLER_PKG, Arrays.asList(
+                DELEGATION_CERT_INSTALL, DELEGATION_CERT_SELECTION));
+        runDeviceTestsAsUser(CERT_INSTALLER_PKG, ".CertSelectionDelegateTest", mUserId);
     }
 
     public void testPermissionGrant() throws Exception {
@@ -450,7 +439,7 @@
         // the same. However we're only testing the FBE case here as we need to set a device
         // password during the test. This would cause FDE devices (e.g. angler) to prompt for the
         // password during reboot, which we can't handle easily.
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
 
@@ -462,6 +451,8 @@
             installAppAsUser(VPN_APP_APK, mUserId);
             executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSet");
             rebootAndWaitUntilReady();
+            // Make sure profile user initialization is complete before proceeding.
+            waitForBroadcastIdle();
             verifyUserCredential(testPassword, mUserId);
             executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSetAfterReboot");
         } finally {
@@ -786,25 +777,15 @@
 
         boolean isManagedProfile = (mPrimaryUserId != mUserId);
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // private key pairs.
-            changeUserCredential("1234", null, mUserId);
 
-            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest", mUserId);
-            assertMetricsLogged(getDevice(), () -> {
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest", mUserId);
+        assertMetricsLogged(getDevice(), () -> {
                 runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest",
                         "testInstallKeyPair", mUserId);
-            }, new DevicePolicyEventWrapper.Builder(EventId.SET_CERT_INSTALLER_PACKAGE_VALUE)
-                    .setAdminPackageName(DEVICE_ADMIN_PKG)
-                    .setStrings(CERT_INSTALLER_PKG)
-                    .build());
-        } finally {
-            if (!isManagedProfile) {
-                // Skip managed profile as dpm doesn't allow clear password
-                changeUserCredential(null, "1234", mUserId);
-            }
-        }
+                }, new DevicePolicyEventWrapper.Builder(EventId.SET_CERT_INSTALLER_PACKAGE_VALUE)
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setStrings(CERT_INSTALLER_PKG)
+                .build());
     }
 
     public interface DelegatedCertInstallerTestAction {
@@ -816,10 +797,6 @@
         installAppAsUser(CERT_INSTALLER_APK, mUserId);
 
         try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // private key pairs.
-            changeUserCredential("1234", null, mUserId);
-
             runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
                     "testManualSetCertInstallerDelegate", mUserId);
 
@@ -827,8 +804,6 @@
         } finally {
             runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
                     "testManualClearCertInstallerDelegate", mUserId);
-
-            changeUserCredential(null, "1234", mUserId);
         }
     }
 
@@ -1038,7 +1013,7 @@
     }
 
     public void testTrustAgentInfo() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         executeDeviceTestClass(".TrustAgentInfoTest");
@@ -1085,7 +1060,7 @@
     }
 
     public void testRequiredStrongAuthTimeout() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         executeDeviceTestClass(".RequiredStrongAuthTimeoutTest");
@@ -1115,7 +1090,7 @@
     }
 
     public void testResetPasswordWithToken() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         // If ResetPasswordWithTokenTest for managed profile is executed before device owner and
@@ -1136,7 +1111,7 @@
     }
 
     public void testGetCurrentFailedPasswordAttempts() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         final String testPassword = "1234";
@@ -1168,14 +1143,14 @@
     }
 
     public void testPasswordExpiration() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         executeDeviceTestClass(".PasswordExpirationTest");
     }
 
     public void testGetPasswordExpiration() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         executeDeviceTestMethod(".GetPasswordExpirationTest",
@@ -1252,16 +1227,7 @@
             return;
         }
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // CA certificates.
-            changeUserCredential("1234", null, mUserId);
-            // Verify the credential immediately to unlock the work profile challenge
-            verifyUserCredential("1234", mUserId);
-            executeDeviceTestClass(".KeyManagementTest");
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
+        executeDeviceTestClass(".KeyManagementTest");
     }
 
     public void testInstallKeyPairLogged() throws Exception {
@@ -1269,26 +1235,16 @@
             return;
         }
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // CA certificates.
-            changeUserCredential("1234", null, mUserId);
-            // Verify the credential immediately to unlock the work profile challenge
-            verifyUserCredential("1234", mUserId);
-            assertMetricsLogged(getDevice(), () -> {
+        assertMetricsLogged(getDevice(), () -> {
                 executeDeviceTestMethod(".KeyManagementTest", "testCanInstallCertChain");
-            }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_KEY_PAIR_VALUE)
-                        .setAdminPackageName(DEVICE_ADMIN_PKG)
-                        .setBoolean(false)
-                        .build(),
+                }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_KEY_PAIR_VALUE)
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(false)
+                .build(),
                 new DevicePolicyEventWrapper.Builder(EventId.REMOVE_KEY_PAIR_VALUE)
-                        .setAdminPackageName(DEVICE_ADMIN_PKG)
-                        .setBoolean(false)
-                        .build());
-
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(false)
+                .build());
     }
 
     public void testGenerateKeyPairLogged() throws Exception {
@@ -1296,31 +1252,22 @@
             return;
         }
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // CA certificates.
-            changeUserCredential("1234", null, mUserId);
-            // Verify the credential immediately to unlock the work profile challenge
-            verifyUserCredential("1234", mUserId);
-            assertMetricsLogged(getDevice(), () -> {
+        assertMetricsLogged(getDevice(), () -> {
                 executeDeviceTestMethod(
                         ".KeyManagementTest", "testCanGenerateKeyPairWithKeyAttestation");
-            }, new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
-                        .setAdminPackageName(DEVICE_ADMIN_PKG)
-                        .setBoolean(false)
-                        .setInt(0)
-                        .setStrings("RSA")
-                        .build(),
+                }, new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(false)
+                .setInt(0)
+                .setStrings("RSA")
+                .build(),
                 new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
-                        .setAdminPackageName(DEVICE_ADMIN_PKG)
-                        .setBoolean(false)
-                        .setInt(0)
-                        .setStrings("EC")
-                        .build());
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(false)
+                .setInt(0)
+                .setStrings("EC")
+                .build());
 
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
     }
 
     public void testSetKeyPairCertificateLogged() throws Exception {
@@ -1328,22 +1275,12 @@
             return;
         }
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for installing
-            // CA certificates.
-            changeUserCredential("1234", null, mUserId);
-            // Verify the credential immediately to unlock the work profile challenge
-            verifyUserCredential("1234", mUserId);
-            assertMetricsLogged(getDevice(), () -> {
+        assertMetricsLogged(getDevice(), () -> {
                 executeDeviceTestMethod(".KeyManagementTest", "testCanSetKeyPairCert");
-            }, new DevicePolicyEventWrapper.Builder(EventId.SET_KEY_PAIR_CERTIFICATE_VALUE)
-                        .setAdminPackageName(DEVICE_ADMIN_PKG)
-                        .setBoolean(false)
-                        .build());
-
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
+                }, new DevicePolicyEventWrapper.Builder(EventId.SET_KEY_PAIR_CERTIFICATE_VALUE)
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(false)
+                .build());
     }
 
     public void testPermittedAccessibilityServices() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
index e4bf61c..fe3998d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
@@ -64,7 +64,7 @@
 
     /** Test for resetPassword for all devices. */
     public void testResetPassword() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
@@ -72,7 +72,7 @@
 
     /** Additional test for resetPassword for FBE-enabled devices. */
     public void testResetPasswordFbe() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 555cfca..0d6225c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -109,8 +109,7 @@
         super.setUp();
 
         // We need multi user to be supported in order to create a profile of the user owner.
-        mHasFeature = mHasFeature && hasDeviceFeature(
-                "android.software.managed_users");
+        mHasFeature = mHasFeature && hasDeviceFeature("android.software.managed_users");
         mHasNfcFeature = hasDeviceFeature("android.hardware.nfc");
 
         if (mHasFeature) {
@@ -151,6 +150,14 @@
         super.tearDown();
     }
 
+    public void testManagedProfilesSupportedWithLockScreenOnly() throws Exception {
+        if (mHasFeature) {
+            // Managed profiles should be only supported if the device supports the secure lock
+            // screen feature.
+            assertTrue(mHasSecureLockScreen);
+        }
+    }
+
     public void testManagedProfileSetup() throws Exception {
         if (!mHasFeature) {
             return;
@@ -235,7 +242,7 @@
     }
 
     public void testLockNowWithKeyEviction() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
         changeUserCredential("1234", null, mProfileUserId);
@@ -1225,7 +1232,7 @@
     }
 
     public void testTrustAgentInfo() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         // Set and get trust agent config using child dpm instance.
@@ -1300,7 +1307,7 @@
     }
 
     public void testResetPasswordWithTokenBeforeUnlock() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
 
@@ -1321,7 +1328,7 @@
      * the device lock.
      */
     public void testResetPasswordTokenUsableAfterClearingLock() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
         final String devicePassword = "1234";
@@ -1348,7 +1355,7 @@
     }
 
     public void testIsUsingUnifiedPassword() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
 
@@ -1361,7 +1368,7 @@
     }
 
     public void testUnlockWorkProfile_deviceWidePassword() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
         String password = "0000";
@@ -1383,7 +1390,7 @@
     }
 
     public void testRebootDevice_unifiedPassword() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         // Waiting before rebooting prevents flakiness.
@@ -1404,7 +1411,7 @@
     }
 
     public void testRebootDevice_separatePasswords() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         // Waiting before rebooting prevents flakiness.
@@ -1438,12 +1445,7 @@
         assertMetricsLogged(getDevice(), () -> {
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
                     "testCrossProfileCalendarPackage", mProfileUserId);
-        }, new DevicePolicyEventWrapper.Builder(EventId.ADD_CROSS_PROFILE_CALENDAR_PACKAGE_VALUE)
-                    .setAdminPackageName(MANAGED_PROFILE_PKG)
-                    .setStrings(MANAGED_PROFILE_PKG)
-                    .build(),
-            new DevicePolicyEventWrapper
-                    .Builder(EventId.REMOVE_CROSS_PROFILE_CALENDAR_PACKAGE_VALUE)
+        }, new DevicePolicyEventWrapper.Builder(EventId.SET_CROSS_PROFILE_CALENDAR_PACKAGES_VALUE)
                     .setAdminPackageName(MANAGED_PROFILE_PKG)
                     .setStrings(MANAGED_PROFILE_PKG)
                     .build());
@@ -1454,6 +1456,7 @@
             return;
         }
         runCrossProfileCalendarTestsWhenWhitelistedAndEnabled();
+        runCrossProfileCalendarTestsWhenAllPackagesWhitelisted();
         runCrossProfileCalendarTestsWhenDisabled();
         runCrossProfileCalendarTestsWhenNotWhitelisted();
     }
@@ -1492,7 +1495,50 @@
         } finally {
             // Cleanup.
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
-                    "testRemoveManagedProfilePackageFromWhitelist", mProfileUserId);
+                    "testCleanupWhitelist", mProfileUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testDisableCrossProfileCalendarSettings", mProfileUserId);
+        }
+    }
+
+    private void runCrossProfileCalendarTestsWhenAllPackagesWhitelisted() throws Exception {
+        try {
+            // Setup. Allow all packages to access cross-profile calendar APIs by setting
+            // the whitelist to null, enable cross-profile calendar in settings,
+            // and insert test data into calendar provider.
+            // All setups should be done in managed profile.
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testWhitelistAllPackages", mProfileUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testAddTestCalendarDataForWorkProfile", mProfileUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testEnableCrossProfileCalendarSettings", mProfileUserId);
+
+            // Testing.
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_getCorrectWorkCalendarsWhenEnabled", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_getCorrectWorkEventsWhenEnabled", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_getCorrectWorkInstancesWhenEnabled", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_getCorrectWorkInstancesByDayWhenEnabled", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_canAccessWorkInstancesSearch1", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_canAccessWorkInstancesSearch2", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_canAccessWorkInstancesSearchByDay", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testPrimaryProfile_getExceptionWhenQueryNonWhitelistedColumns", mParentUserId);
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testViewEventCrossProfile_intentReceivedWhenWhitelisted", mParentUserId);
+        } finally {
+            // Cleanup.
+            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+                    "testCleanupWhitelist", mProfileUserId);
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
                     "testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
@@ -1523,7 +1569,7 @@
         } finally {
             // Cleanup.
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
-                    "testRemoveManagedProfilePackageFromWhitelist", mProfileUserId);
+                    "testCleanupWhitelist", mProfileUserId);
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
                     "testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
         }
@@ -1559,7 +1605,7 @@
     }
 
     public void testCreateSeparateChallengeChangedLogged() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         assertMetricsLogged(getDevice(), () -> {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index 31d03fd..0417844 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -159,7 +159,7 @@
 
     @Override
     public void testResetPasswordWithToken() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
         // Execute the test method that's guaranteed to succeed. See also test in base class
@@ -209,22 +209,15 @@
             return;
         }
 
-        try {
-            // Set a non-empty device lockscreen password, which is a precondition for interacting
-            // with KeyStore.
-            changeUserCredential("1234", null, mUserId);
-            // Test that Device ID attestation for the profile owner does not work without grant.
-            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
-                    "testFailsWithoutProfileOwnerIdsGrant", mUserId);
+        // Test that Device ID attestation for the profile owner does not work without grant.
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
+                "testFailsWithoutProfileOwnerIdsGrant", mUserId);
 
-            // Test that Device ID attestation for the profile owner works with a grant.
-            grantProfileOwnerDeviceIdsAccess();
+        // Test that Device ID attestation for the profile owner works with a grant.
+        grantProfileOwnerDeviceIdsAccess();
 
-            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
-                    "testSucceedsWithProfileOwnerIdsGrant", mUserId);
-        } finally {
-            changeUserCredential(null, "1234", mUserId);
-        }
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
+                "testSucceedsWithProfileOwnerIdsGrant", mUserId);
     }
 
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
index fd5b2bf..47b3539 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
@@ -62,7 +62,7 @@
      */
     @Override
     public void testResetPassword() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !mHasSecureLockScreen) {
             return;
         }
 
@@ -75,7 +75,7 @@
      */
     @Override
     public void testResetPasswordFbe() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
+        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
             return;
         }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
index 9be917e..958009f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
@@ -11,6 +11,10 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        if (!mHasSecureLockScreen) {
+          return;
+        }
+
         if (!getDevice().executeShellCommand("cmd lock_settings verify")
                 .startsWith("Lock credential verified successfully")) {
             fail("Please remove the device screen lock before running this test");
@@ -21,12 +25,17 @@
 
     @Override
     protected void tearDown() throws Exception {
-        getDevice().uninstallPackage(PKG);
+        if (mHasSecureLockScreen) {
+            getDevice().uninstallPackage(PKG);
+        }
 
         super.tearDown();
     }
 
     public void testGetPasswordComplexity() throws Exception {
+        if (!mHasSecureLockScreen) {
+            return;
+        }
         runDeviceTestsAsUser(PKG, CLS, mPrimaryUserId);
     }
 }
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk
new file mode 100644
index 0000000..875feb5
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm
new file mode 100644
index 0000000..bc79e55
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk
new file mode 100644
index 0000000..6760973
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm
new file mode 100644
index 0000000..4471f69
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
index 766034a..15bb39b 100644
--- a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
+++ b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.cts.dexmetadata;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -24,9 +25,8 @@
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.FileUtil;
-
-import java.io.ByteArrayOutputStream;
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -37,7 +37,6 @@
 import java.nio.file.Paths;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
-
 import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
@@ -56,15 +55,25 @@
 
     private static final String APK_BASE = "CtsDexMetadataSplitApp.apk";
     private static final String APK_FEATURE_A = "CtsDexMetadataSplitAppFeatureA.apk";
+    private static final String APK_BASE_WITH_VDEX = "CtsDexMetadataSplitAppWithVdex.apk";
+    private static final String APK_FEATURE_A_WITH_VDEX
+            = "CtsDexMetadataSplitAppFeatureAWithVdex.apk";
 
     private static final String DM_BASE = "CtsDexMetadataSplitApp.dm";
     private static final String DM_FEATURE_A = "CtsDexMetadataSplitAppFeatureA.dm";
+    private static final String DM_BASE_WITH_VDEX = "CtsDexMetadataSplitAppWithVdex.dm";
+    private static final String DM_FEATURE_A_WITH_VDEX
+    = "CtsDexMetadataSplitAppFeatureAWithVdex.dm";
 
     private File mTmpDir;
     private File mApkBaseFile = null;
     private File mApkFeatureAFile = null;
+    private File mApkBaseFileWithVdex = null;
+    private File mApkFeatureAFileWithVdex = null;
     private File mDmBaseFile = null;
     private File mDmFeatureAFile = null;
+    private File mDmBaseFileWithVdex = null;
+    private File mDmFeatureAFileWithVdex = null;
     private boolean mShouldRunTests;
 
     /**
@@ -83,8 +92,12 @@
             mTmpDir = FileUtil.createTempDir("InstallDexMetadataHostTest");
             mApkBaseFile = extractResource(APK_BASE, mTmpDir);
             mApkFeatureAFile = extractResource(APK_FEATURE_A, mTmpDir);
+            mApkBaseFileWithVdex = extractResource(APK_BASE_WITH_VDEX, mTmpDir);
+            mApkFeatureAFileWithVdex = extractResource(APK_FEATURE_A_WITH_VDEX, mTmpDir);
             mDmBaseFile = extractResource(DM_BASE, mTmpDir);
             mDmFeatureAFile = extractResource(DM_FEATURE_A, mTmpDir);
+            mDmBaseFileWithVdex = extractResource(DM_BASE_WITH_VDEX, mTmpDir);
+            mDmFeatureAFileWithVdex = extractResource(DM_FEATURE_A_WITH_VDEX, mTmpDir);
         }
     }
 
@@ -204,6 +217,29 @@
         assertArrayEquals(expectedProfileBytes, snapshotProfileBytes);
     }
 
+    /**
+     * Verify .dm installation for stand-alone base (no splits) with vdex file.
+     */
+    @Test
+    public void testInstallDmForBaseWithVdex() throws Exception {
+        new InstallMultiple().addApk(mApkBaseFileWithVdex).addDm(mDmBaseFileWithVdex).run();
+        assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
+
+        assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBase"));
+    }
+
+    /**
+     * Verify .dm installation for base and splits with vdex files.
+     */
+    @Test
+    public void testInstallDmForBaseAndSplitWithVdex() throws Exception {
+        new InstallMultiple().addApk(mApkBaseFileWithVdex).addDm(mDmBaseFileWithVdex)
+                .addApk(mApkFeatureAFileWithVdex).addDm(mDmFeatureAFileWithVdex).run();
+        assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
+
+        assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseAndSplit"));
+    }
+
     /** Verify that the use of profiles is enabled on the device. */
     private void assumeProfilesAreEnabled() throws Exception {
         String useProfiles = getDevice().executeShellCommand(
diff --git a/hostsidetests/gputools/apps/AndroidManifest.xml b/hostsidetests/gputools/apps/AndroidManifest.xml
index de8130f..fab44c3 100755
--- a/hostsidetests/gputools/apps/AndroidManifest.xml
+++ b/hostsidetests/gputools/apps/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.rootlessgpudebug.app">>
 
-    <application>
+    <application android:extractNativeLibs="true" >
         <activity android:name=".RootlessGpuDebugDeviceActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/hostsidetests/gputools/layers/AndroidManifest.xml b/hostsidetests/gputools/layers/AndroidManifest.xml
index 957b047..2b187ad 100755
--- a/hostsidetests/gputools/layers/AndroidManifest.xml
+++ b/hostsidetests/gputools/layers/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.rootlessgpudebug.LAYERS.app">
 
-    <application android:debuggable="false" android:hasCode="false">
+    <application android:extractNativeLibs="true" android:debuggable="false"
+        android:hasCode="false">
     </application>
 
 </manifest>
diff --git a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
index 68e9aab..7b04ff91 100644
--- a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
+++ b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
@@ -116,22 +116,24 @@
             device.setSetting("global", "hidden_api_policy", "1");
         }
 
-        RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName, RUNNER,
-                device.getIDevice());
-        // set a max deadline limit to avoid hanging forever
-        runner.setMaxTimeToOutputResponse(2, TimeUnit.MINUTES);
+        try {
+            RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName, RUNNER,
+                    device.getIDevice());
+            // set a max deadline limit to avoid hanging forever
+            runner.setMaxTimeToOutputResponse(2, TimeUnit.MINUTES);
 
-        AttachAgent aa = new AttachAgent(device, mTestPackageName, mTestApk);
-        aa.prepare();
-        TestResults tr = new TestResults(aa);
+            AttachAgent aa = new AttachAgent(device, mTestPackageName, mTestApk);
+            aa.prepare();
+            TestResults tr = new TestResults(aa);
 
-        device.runInstrumentationTests(runner, tr);
+            device.runInstrumentationTests(runner, tr);
 
-        assertTrue(tr.getErrors(), tr.hasStarted());
-        assertFalse(tr.getErrors(), tr.hasFailed());
-
-        if (disable_hidden_api) {
-            device.setSetting("global", "hidden_api_policy", old_hiddenapi_setting);
+            assertTrue(tr.getErrors(), tr.hasStarted());
+            assertFalse(tr.getErrors(), tr.hasFailed());
+        } finally {
+            if (disable_hidden_api) {
+                device.setSetting("global", "hidden_api_policy", old_hiddenapi_setting);
+            }
         }
     }
 
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
index 90a3ce4..c61b7d3 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
@@ -17,6 +17,7 @@
 package com.android.cts.net.hostside;
 
 import android.content.Intent;
+import android.net.ProxyInfo;
 import android.net.VpnService;
 import android.os.ParcelFileDescriptor;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -113,6 +114,8 @@
             }
         }
 
+        ProxyInfo vpnProxy = intent.getParcelableExtra(packageName + ".httpProxy");
+        builder.setHttpProxy(vpnProxy);
         builder.setMtu(MTU);
         builder.setBlocking(true);
         builder.setSession("MyVpnService");
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index 48f0afb..75fc6f1 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -19,6 +19,7 @@
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.*;
 
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
@@ -27,6 +28,8 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.Proxy;
+import android.net.ProxyInfo;
 import android.net.VpnService;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
@@ -45,6 +48,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.compatibility.common.util.BlockingBroadcastReceiver;
 import com.android.cts.net.hostside.IRemoteSocketFactory;
 
 import java.io.BufferedReader;
@@ -197,9 +201,8 @@
     }
 
     private void startVpn(
-            String[] addresses, String[] routes,
-            String allowedApplications, String disallowedApplications) throws Exception {
-
+        String[] addresses, String[] routes, String allowedApplications,
+        String disallowedApplications, ProxyInfo proxyInfo) throws Exception {
         prepareVpn();
 
         // Register a callback so we will be notified when our VPN comes up.
@@ -225,7 +228,8 @@
                 .putExtra(mPackageName + ".addresses", TextUtils.join(",", addresses))
                 .putExtra(mPackageName + ".routes", TextUtils.join(",", routes))
                 .putExtra(mPackageName + ".allowedapplications", allowedApplications)
-                .putExtra(mPackageName + ".disallowedapplications", disallowedApplications);
+                .putExtra(mPackageName + ".disallowedapplications", disallowedApplications)
+                .putExtra(mPackageName + ".httpProxy", proxyInfo);
         mActivity.startService(intent);
         synchronized (mLock) {
             if (mNetwork == null) {
@@ -573,7 +577,7 @@
 
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"0.0.0.0/0", "::/0"},
-                 "", "");
+                 "", "", null);
 
         assertSocketClosed(fd, TEST_HOST);
 
@@ -589,7 +593,7 @@
         String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"192.0.2.0/24", "2001:db8::/32"},
-                 allowedApps, "");
+                 allowedApps, "", null);
 
         assertSocketClosed(fd, TEST_HOST);
 
@@ -611,7 +615,7 @@
         Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps);
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"192.0.2.0/24", "2001:db8::/32"},
-                 "", disallowedApps);
+                 "", disallowedApps, null);
 
         assertSocketStillOpen(localFd, TEST_HOST);
         assertSocketStillOpen(remoteFd, TEST_HOST);
@@ -620,7 +624,6 @@
     }
 
     public void testGetConnectionOwnerUidSecurity() throws Exception {
-
         if (!supportedHardware()) return;
 
         DatagramSocket s;
@@ -637,4 +640,155 @@
             return;
         }
     }
+
+    public void testSetProxy() throws  Exception {
+        if (!supportedHardware()) return;
+        ProxyInfo initialProxy = mCM.getDefaultProxy();
+        // Receiver for the proxy change broadcast.
+        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+        proxyBroadcastReceiver.register();
+
+        String allowedApps = mPackageName;
+        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
+                testProxyInfo);
+
+        // Check that the proxy change broadcast is received
+        try {
+            assertNotNull("No proxy change was broadcast when VPN is connected.",
+                    proxyBroadcastReceiver.awaitForBroadcast());
+        } finally {
+            proxyBroadcastReceiver.unregisterQuietly();
+        }
+
+        // Proxy is set correctly in network and in link properties.
+        assertNetworkHasExpectedProxy(testProxyInfo, mNetwork);
+        assertDefaultProxy(testProxyInfo);
+
+        proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+        proxyBroadcastReceiver.register();
+        stopVpn();
+        try {
+            assertNotNull("No proxy change was broadcast when VPN was disconnected.",
+                    proxyBroadcastReceiver.awaitForBroadcast());
+        } finally {
+            proxyBroadcastReceiver.unregisterQuietly();
+        }
+
+        // After disconnecting from VPN, the proxy settings are the ones of the initial network.
+        assertDefaultProxy(initialProxy);
+    }
+
+    public void testSetProxyDisallowedApps() throws Exception {
+        if (!supportedHardware()) return;
+        ProxyInfo initialProxy = mCM.getDefaultProxy();
+
+        // If adb TCP port opened, this test may running by adb over TCP.
+        // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test,
+        // see b/119382723.
+        // Note: The test don't support running adb over network for root device
+        String disallowedApps = mPackageName + ",com.android.shell";
+        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+                new String[] {"0.0.0.0/0", "::/0"}, "", disallowedApps,
+                testProxyInfo);
+
+        // The disallowed app does has the proxy configs of the default network.
+        assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
+        assertDefaultProxy(initialProxy);
+    }
+
+    public void testNoProxy() throws Exception {
+        if (!supportedHardware()) return;
+        ProxyInfo initialProxy = mCM.getDefaultProxy();
+        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+        proxyBroadcastReceiver.register();
+        String allowedApps = mPackageName;
+        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null);
+
+        try {
+            assertNotNull("No proxy change was broadcast.",
+                    proxyBroadcastReceiver.awaitForBroadcast());
+        } finally {
+            proxyBroadcastReceiver.unregisterQuietly();
+        }
+
+        // The VPN network has no proxy set.
+        assertNetworkHasExpectedProxy(null, mNetwork);
+
+        proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+        proxyBroadcastReceiver.register();
+        stopVpn();
+        try {
+            assertNotNull("No proxy change was broadcast.",
+                    proxyBroadcastReceiver.awaitForBroadcast());
+        } finally {
+            proxyBroadcastReceiver.unregisterQuietly();
+        }
+        // After disconnecting from VPN, the proxy settings are the ones of the initial network.
+        assertDefaultProxy(initialProxy);
+        assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
+    }
+
+    public void testBindToNetworkWithProxy() throws Exception {
+        if (!supportedHardware()) return;
+        String allowedApps = mPackageName;
+        Network initialNetwork = mCM.getActiveNetwork();
+        ProxyInfo initialProxy = mCM.getDefaultProxy();
+        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+        // Receiver for the proxy change broadcast.
+        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+        proxyBroadcastReceiver.register();
+        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
+                testProxyInfo);
+
+        assertDefaultProxy(testProxyInfo);
+        mCM.bindProcessToNetwork(initialNetwork);
+        try {
+            assertNotNull("No proxy change was broadcast.",
+                proxyBroadcastReceiver.awaitForBroadcast());
+        } finally {
+            proxyBroadcastReceiver.unregisterQuietly();
+        }
+        assertDefaultProxy(initialProxy);
+    }
+
+    private void assertDefaultProxy(ProxyInfo expected) {
+        assertEquals("Incorrect proxy config.", expected, mCM.getDefaultProxy());
+        String expectedHost = expected == null ? null : expected.getHost();
+        String expectedPort = expected == null ? null : String.valueOf(expected.getPort());
+        assertEquals("Incorrect proxy host system property.", expectedHost,
+            System.getProperty("http.proxyHost"));
+        assertEquals("Incorrect proxy port system property.", expectedPort,
+            System.getProperty("http.proxyPort"));
+    }
+
+    private void assertNetworkHasExpectedProxy(ProxyInfo expected, Network network) {
+        LinkProperties lp = mCM.getLinkProperties(network);
+        assertNotNull("The network link properties object is null.", lp);
+        assertEquals("Incorrect proxy config.", expected, lp.getHttpProxy());
+
+        assertEquals(expected, mCM.getProxyForNetwork(network));
+    }
+
+    class ProxyChangeBroadcastReceiver extends BlockingBroadcastReceiver {
+        private boolean received;
+
+        public ProxyChangeBroadcastReceiver() {
+            super(VpnTest.this.getInstrumentation().getContext(), Proxy.PROXY_CHANGE_ACTION);
+            received = false;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!received) {
+                // Do not call onReceive() more than once.
+                super.onReceive(context, intent);
+            }
+            received = true;
+        }
+    }
 }
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
index 853668c..e34ee89 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
@@ -48,4 +48,20 @@
     public void testGetConnectionOwnerUidSecurity() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testGetConnectionOwnerUidSecurity");
     }
+
+    public void testSetProxy() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxy");
+    }
+
+    public void testSetProxyDisallowedApps() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxyDisallowedApps");
+    }
+
+    public void testNoProxy() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testNoProxy");
+    }
+
+    public void testBindToNetworkWithProxy() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testBindToNetworkWithProxy");
+    }
 }
diff --git a/hostsidetests/seccomp/app/Android.mk b/hostsidetests/seccomp/app/Android.mk
index 041d760..cf15eff 100644
--- a/hostsidetests/seccomp/app/Android.mk
+++ b/hostsidetests/seccomp/app/Android.mk
@@ -47,7 +47,7 @@
 
 LOCAL_PACKAGE_NAME := CtsSeccompDeviceApp
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_PACKAGE)
 
diff --git a/hostsidetests/seccomp/app/AndroidManifest.xml b/hostsidetests/seccomp/app/AndroidManifest.xml
index b8e97e3..538149d 100644
--- a/hostsidetests/seccomp/app/AndroidManifest.xml
+++ b/hostsidetests/seccomp/app/AndroidManifest.xml
@@ -20,6 +20,12 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <service
+            android:name=".IsolatedService"
+            android:isolatedProcess="true"
+            android:exported="false"
+            android:useAppZygote="true">
+        </service>
     </application>
 
     <instrumentation
diff --git a/hostsidetests/seccomp/app/assets/syscalls_blocked.json b/hostsidetests/seccomp/app/assets/syscalls_blocked.json
index 441c8da..a53319b 100644
--- a/hostsidetests/seccomp/app/assets/syscalls_blocked.json
+++ b/hostsidetests/seccomp/app/assets/syscalls_blocked.json
@@ -13,8 +13,22 @@
     "mount": 21,
     "reboot": 88,
     "setdomainname": 121,
+    "setfsgid": 139,
+    "setfsuid": 138,
+    "setgid": 46,
+    "setgid32": 214,
+    "setgroups": 81,
+    "setgroups32": 206,
     "sethostname": 74,
+    "setregid": 71,
+    "setregid32": 204,
+    "setresgid": 170,
+    "setresgid32": 210,
+    "setreuid": 70,
+    "setreuid32": 203,
     "settimeofday": 79,
+    "setuid": 23,
+    "setuid32": 213,
     "swapoff": 115,
     "swapon": 87,
     "syslog": 103,
@@ -33,8 +47,16 @@
     "mount": 40,
     "reboot": 142,
     "setdomainname": 162,
+    "setfsgid": 152,
+    "setfsuid": 151,
+    "setgid": 144,
+    "setgroups": 159,
     "sethostname": 161,
+    "setregid": 143,
+    "setresgid": 149,
+    "setreuid": 145,
     "settimeofday": 170,
+    "setuid": 146,
     "swapoff": 225,
     "swapon": 224,
     "syslog": 116,
@@ -53,8 +75,16 @@
     "mount": 4021,
     "reboot": 4088,
     "setdomainname": 4121,
+    "setfsgid": 4139,
+    "setfsuid": 4138,
+    "setgid": 4046,
+    "setgroups": 4081,
     "sethostname": 4074,
+    "setregid": 4071,
+    "setresgid": 4190,
+    "setreuid": 4070,
     "settimeofday": 4079,
+    "setuid": 4023,
     "swapoff": 4115,
     "swapon": 4087,
     "syslog": 4103,
@@ -73,8 +103,16 @@
     "mount": 5160,
     "reboot": 5164,
     "setdomainname": 5166,
+    "setfsgid": 5121,
+    "setfsuid": 5120,
+    "setgid": 5104,
+    "setgroups": 5114,
     "sethostname": 5165,
+    "setregid": 5112,
+    "setresgid": 5117,
+    "setreuid": 5111,
     "settimeofday": 5159,
+    "setuid": 5103,
     "swapoff": 5163,
     "swapon": 5162,
     "syslog": 5101,
@@ -93,8 +131,22 @@
     "mount": 21,
     "reboot": 88,
     "setdomainname": 121,
+    "setfsgid": 139,
+    "setfsuid": 138,
+    "setgid": 46,
+    "setgid32": 214,
+    "setgroups": 81,
+    "setgroups32": 206,
     "sethostname": 74,
+    "setregid": 71,
+    "setregid32": 204,
+    "setresgid": 170,
+    "setresgid32": 210,
+    "setreuid": 70,
+    "setreuid32": 203,
     "settimeofday": 79,
+    "setuid": 23,
+    "setuid32": 213,
     "swapoff": 115,
     "swapon": 87,
     "syslog": 103,
@@ -113,8 +165,16 @@
     "mount": 165,
     "reboot": 169,
     "setdomainname": 171,
+    "setfsgid": 123,
+    "setfsuid": 122,
+    "setgid": 106,
+    "setgroups": 116,
     "sethostname": 170,
+    "setregid": 114,
+    "setresgid": 119,
+    "setreuid": 113,
     "settimeofday": 164,
+    "setuid": 105,
     "swapoff": 168,
     "swapon": 167,
     "syslog": 103,
diff --git a/hostsidetests/seccomp/app/gen_blacklist.py b/hostsidetests/seccomp/app/gen_blacklist.py
index cf36d11..e39fd9f 100755
--- a/hostsidetests/seccomp/app/gen_blacklist.py
+++ b/hostsidetests/seccomp/app/gen_blacklist.py
@@ -46,6 +46,20 @@
     'setdomainname': 'all',
     'sethostname': 'all',
     'settimeofday': 'all',
+    'setfsgid': 'all',
+    'setfsuid': 'all',
+    'setgid': 'all',
+    'setgid32': 'x86,arm',
+    'setgroups': 'all',
+    'setgroups32': 'x86,arm',
+    'setregid': 'all',
+    'setregid32': 'x86,arm',
+    'setresgid': 'all',
+    'setresgid32': 'x86,arm',
+    'setreuid': 'all',
+    'setreuid32': 'x86,arm',
+    'setuid': 'all',
+    'setuid32': 'x86,arm',
     'swapoff': 'all',
     'swapoff': 'all',
     'swapon': 'all',
diff --git a/hostsidetests/seccomp/app/jni/Android.mk b/hostsidetests/seccomp/app/jni/Android.mk
index 45fb135..3637f27 100644
--- a/hostsidetests/seccomp/app/jni/Android.mk
+++ b/hostsidetests/seccomp/app/jni/Android.mk
@@ -32,4 +32,5 @@
 
 LOCAL_CFLAGS := -Wall -Werror
 
+LOCAL_NDK_STL_VARIANT := c++_static
 include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
index 2257232..1aac7239 100644
--- a/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
+++ b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
@@ -18,6 +18,7 @@
 
 #define LOG_TAG "SeccompTest"
 
+#include <functional>
 #include <android/log.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -37,12 +38,11 @@
  *        1 if blocked, else 0
  * Exceptions: None
  */
-static jboolean testSyscallBlocked(JNIEnv *, jobject, int nr) {
+static jboolean doTestSyscallBlocked(std::function<void()> execSyscall) {
     int pid = fork();
     if (pid == 0) {
-        ALOGI("Calling syscall %d", nr);
-        syscall(nr);
-        return false;
+        execSyscall();
+        exit(0);
     } else {
         int status;
         int ret = waitpid(pid, &status, 0);
@@ -72,9 +72,25 @@
     }
 }
 
+static jboolean testSyscallBlocked(JNIEnv *, jobject, jint nr) {
+    return doTestSyscallBlocked([&](){ ALOGI("Calling syscall %d", nr); syscall(nr); });
+}
+
+static jboolean testSetresuidBlocked(JNIEnv *, jobject, jint ruid, jint euid, jint suid) {
+    return doTestSyscallBlocked([&] {ALOGE("Calling setresuid\n"); setresuid(ruid, euid, suid);});
+}
+
+static jboolean testSetresgidBlocked(JNIEnv *, jobject, jint rgid, jint egid, jint sgid) {
+    return doTestSyscallBlocked([&] {ALOGE("Calling setresgid\n"); setresgid(rgid, egid, sgid);});
+}
+
 static JNINativeMethod gMethods[] = {
     { "testSyscallBlocked", "(I)Z",
             (void*) testSyscallBlocked },
+    { "testSetresuidBlocked", "(III)Z",
+            (void*) testSetresuidBlocked },
+    { "testSetresgidBlocked", "(III)Z",
+            (void*) testSetresgidBlocked },
 };
 
 int register_android_seccomp_cts_app_SeccompTest(JNIEnv* env)
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java
new file mode 100644
index 0000000..2546c57
--- /dev/null
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.seccomp.cts.app;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class IsolatedService extends Service {
+    static final String TAG = "IsolatedService";
+
+    static final int MSG_GET_SECCOMP_RESULT = 1;
+
+    static final int MSG_SECCOMP_RESULT = 2;
+    final Messenger mMessenger = new Messenger(new ServiceHandler());
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mMessenger.getBinder();
+    }
+
+    static class ServiceHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case (MSG_GET_SECCOMP_RESULT):
+                    int result = ZygotePreload.getSeccomptestResult() ? 1 : 0;
+                    try {
+                        msg.replyTo.send(Message.obtain(null, MSG_SECCOMP_RESULT, result, 0));
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to send seccomp test result", e);
+                    }
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
index 42ea6c2..1f066dc 100644
--- a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
@@ -20,10 +20,23 @@
 import java.io.InputStream;
 import java.util.Iterator;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.res.AssetManager;
+import android.os.ConditionVariable;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
 import com.android.compatibility.common.util.CpuFeatures;
 import org.json.JSONObject;
 import org.json.JSONException;
@@ -44,19 +57,39 @@
         System.loadLibrary("ctsseccomp_jni");
     }
 
+    static final String TAG = "SeccompDeviceTest";
+
+    protected Context mContext;
+
+    // This is flagged whenever we have obtained the test result from the isolated
+    // service; it allows us to block the test until the results are in.
+    private final ConditionVariable mResultCondition = new ConditionVariable();
+
+    private boolean mAppZygoteResult;
+    private Messenger mMessenger;
+    private HandlerThread mHandlerThread;
+
+    // The service start can take a long time, because seccomp denials will
+    // cause process crashes and dumps, which we waitpid() for sequentially.
+    private static final int SERVICE_START_TIMEOUT_MS = 120000;
+
     private JSONObject mAllowedSyscallMap;
     private JSONObject mBlockedSyscallMap;
 
     @Before
     public void initializeSyscallMap() throws IOException, JSONException {
-        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        AssetManager manager = context.getAssets();
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        AssetManager manager = mContext.getAssets();
         try (InputStream is = manager.open("syscalls_allowed.json")) {
             mAllowedSyscallMap = new JSONObject(readInputStreamFully(is));
         }
         try (InputStream is = manager.open("syscalls_blocked.json")) {
             mBlockedSyscallMap = new JSONObject(readInputStreamFully(is));
         }
+        mHandlerThread = new HandlerThread("HandlerThread");
+        mHandlerThread.start();
+        Looper looper = mHandlerThread.getLooper();
+        mMessenger = new Messenger(new IncomingHandler(looper));
     }
 
     @Test
@@ -79,6 +112,84 @@
         }
     }
 
+    class IncomingHandler extends Handler {
+        IncomingHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case IsolatedService.MSG_SECCOMP_RESULT:
+                    mAppZygoteResult = (msg.arg1 == 1);
+                    mResultCondition.open();
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+	}
+
+    class IsolatedConnection implements ServiceConnection {
+        private final ConditionVariable mConnectedCondition = new ConditionVariable();
+        private Messenger mService;
+
+        public void onServiceConnected(ComponentName name, IBinder binder) {
+            mService = new Messenger(binder);
+            mConnectedCondition.open();
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            mConnectedCondition.close();
+        }
+
+        public boolean getTestResult() {
+            boolean connected = mConnectedCondition.block(SERVICE_START_TIMEOUT_MS);
+            if (!connected) {
+               Log.e(TAG, "Failed to wait for IsolatedService to bind.");
+               return false;
+            }
+            Message msg = Message.obtain(null, IsolatedService.MSG_GET_SECCOMP_RESULT);
+            msg.replyTo = mMessenger;
+            try {
+                mService.send(msg);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to send message to IsolatedService to get test result.", e);
+                return false;
+            }
+
+            // Wait for result and return it
+            mResultCondition.block();
+
+            return mAppZygoteResult;
+        }
+    }
+
+    private IsolatedConnection bindService(Class<?> cls) {
+        Intent intent = new Intent();
+        intent.setClass(mContext, cls);
+        IsolatedConnection conn = new IsolatedConnection();
+        mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+
+        return conn;
+    }
+
+    @Test
+    public void testAppZygoteSyscalls() {
+        // Isolated services that spawn from the application Zygote are allowed
+        // to preload code in a security context that is allowed to use
+        // setresuid() / setresgid() in a limited range; this test enforces
+        // we allow calls within the range, and reject those outside them.
+        // This is done from the ZygotePreload class (which runs in the app zygote
+        // context); here we just wait for the service to come up, and ask it
+        // whether the tests were executed successfully. We have to ask the service
+        // because that is the only process that we can talk to that shares the
+        // same address space as the ZygotePreload class, which holds the test
+        // result.
+        IsolatedConnection conn = bindService(IsolatedService.class);
+        boolean testResult = conn.getTestResult();
+        Assert.assertTrue("seccomp tests in application zygote failed; see logs.", testResult);
+    }
+
     private static String getCurrentArch() {
         if (CpuFeatures.isArm64Cpu()) {
             return "arm64";
@@ -120,4 +231,6 @@
     }
 
     private static final native boolean testSyscallBlocked(int nr);
+    protected static final native boolean testSetresuidBlocked(int ruid, int euid, int suid);
+    protected static final native boolean testSetresgidBlocked(int rgid, int egid, int sgid);
 }
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
new file mode 100644
index 0000000..270e558
--- /dev/null
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.seccomp.cts.app;
+
+import android.os.Process;
+import android.util.Log;
+
+public class ZygotePreload {
+    static final String TAG = "SeccompDeviceTest";
+
+    static boolean sResult = false;
+
+    static private boolean testSetResUidGidBlocked(int rid, int eid, int sid) {
+        if (!SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
+            Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
+                    + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+                    + " is wrongly allowed.");
+            return false;
+        }
+        if (!SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
+            Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
+                    + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+                    + " is wrongly allowed.");
+            return false;
+        }
+
+        return true;
+    }
+
+    static private boolean testSetResUidGidAllowed(int rid, int eid, int sid) {
+        if (SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
+            Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
+                    + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+                    + " is wrongly blocked.");
+            return false;
+        }
+        if (SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
+            Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
+                    + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+                    + " is wrongly blocked.");
+            return false;
+        }
+
+        return true;
+    }
+
+    static synchronized public boolean getSeccomptestResult() {
+        return sResult;
+    }
+
+    /*
+     * This is called from the app_zygote security context, which has two seccomp
+     * filters in place:
+     * 1) The regular app seccomp filter (which allows setresuid/setresgid)
+     * 2) A setresuid/setresgid limiting filter, which restricts the calls to
+     *    setresuid/setresgid to be in a particular range.
+     *
+     * This test enforces 2) is in place.
+     */
+    static synchronized public void doPreload() {
+        boolean result = true;
+
+        // root uid
+        result &= testSetResUidGidBlocked(0, 0, 0);
+        // system uid
+        result &= testSetResUidGidBlocked(Process.SYSTEM_UID, Process.SYSTEM_UID,
+                Process.SYSTEM_UID);
+        // mix of uids
+        result &= testSetResUidGidBlocked(0, Process.SYSTEM_UID,
+                Process.SYSTEM_UID);
+
+        // an app uid
+        result &= testSetResUidGidBlocked(Process.FIRST_APPLICATION_UID,
+                Process.FIRST_APPLICATION_UID, Process.FIRST_APPLICATION_UID);
+        result &= testSetResUidGidBlocked(Process.LAST_APPLICATION_UID,
+                Process.LAST_APPLICATION_UID, Process.LAST_APPLICATION_UID);
+
+        // an isolated process uid
+        result &= testSetResUidGidBlocked(Process.FIRST_ISOLATED_UID,
+                Process.FIRST_ISOLATED_UID, Process.FIRST_ISOLATED_UID);
+        result &= testSetResUidGidBlocked(Process.LAST_ISOLATED_UID, Process.LAST_ISOLATED_UID,
+                Process.LAST_ISOLATED_UID);
+
+        // an allowed app zygote UID
+        // TODO this test assumes no other isolated app zygotes are currently running!
+        result &= testSetResUidGidAllowed(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+
+        // off-by-one
+        result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1);
+
+        // mixed allowed rgid with dis-allowed euid and suid (and variants)
+        result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0, 0);
+        result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
+        result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
+        result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+        result &= testSetResUidGidBlocked(0, 0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+        result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0,
+                Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+
+        // a disallowed app zygote UID
+        result &= testSetResUidGidBlocked(Process.LAST_APP_ZYGOTE_ISOLATED_UID,
+                Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.LAST_APP_ZYGOTE_ISOLATED_UID);
+
+        // Store result
+        sResult = result;
+    }
+}
diff --git a/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
index 2a7242b..1d845f9 100644
--- a/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
+++ b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
@@ -41,6 +41,7 @@
 
     private static final String TEST_CTS_SYSCALL_BLOCKED = "testCTSSyscallBlocked";
     private static final String TEST_CTS_SYSCALL_ALLOWED = "testCTSSyscallAllowed";
+    private static final String TEST_CTS_SYSCALL_APP_ZYGOTE = "testAppZygoteSyscalls";
 
     @Before
     public void setUp() throws Exception {
@@ -57,6 +58,11 @@
         Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SYSCALL_ALLOWED));
     }
 
+    @Test
+    public void testAppZygoteSyscalls() throws Exception {
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SYSCALL_APP_ZYGOTE));
+    }
+
     @After
     public void tearDown() throws Exception {
         uninstallPackage(getDevice(), TEST_PKG);
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
index 5b40654..83227af 100755
--- a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
@@ -94,6 +94,8 @@
             outMsg->body.motion.metaState = msg.body.motion.metaState;
             // int32_t buttonState
             outMsg->body.motion.buttonState = msg.body.motion.buttonState;
+            // MotionClassification classification
+            outMsg->body.motion.classification = msg.body.motion.classification;
             // int32_t edgeFlags
             outMsg->body.motion.edgeFlags = msg.body.motion.edgeFlags;
             // nsecs_t downTime
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
index 5561115..498e85f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
 LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
 LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
index 4a4301f..a6a520f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
@@ -25,7 +25,7 @@
         libpac \
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
 LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
 LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
index 4527c0c..9a7e62a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
@@ -28,7 +28,7 @@
         AdbUtils.runCommandLine("logcat -c" , getDevice());
         AdbUtils.runPoc("CVE-2016-2419", getDevice(), 60);
         String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
-        assertNotMatches("[\\s\\n\\S]*IOMX_InfoLeak b26323455[\\s\\n\\S]*", logcat);
+        assertNotMatchesMultiLine("IOMX_InfoLeak b26323455", logcat);
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index 886ebaf..d866a5a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -29,7 +29,7 @@
         AdbUtils.runPoc("CVE-2016-2460", getDevice(), 60);
 
         String logcat =  AdbUtils.runCommandLine("logcat -d", getDevice());
-        assertNotMatches("[\\s\\n\\S]*IGraphicBufferProducer_Info is Leaked[\\s\\n\\S]*", logcat);
+        assertNotMatchesMultiLine("IGraphicBufferProducer_Info is Leaked", logcat);
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index b6bb97b..bb18b0d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -29,7 +29,7 @@
         AdbUtils.runCommandLine("logcat -c", getDevice());
         AdbUtils.runPoc("CVE-2012-6702", getDevice(), 60);
         String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
-        assertNotMatches("[\\s\\n\\S]*fail: encountered same random values![\\s\\n\\S]*", logcat);
+        assertNotMatchesMultiLine("fail: encountered same random values!", logcat);
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index 27ded73..e2e5134 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -27,7 +27,7 @@
       AdbUtils.runCommandLine("logcat -c", getDevice());
       AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
       String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
-      assertNotMatches("[\\s\\n\\S]*Bugreports file in wrong path[\\s\\n\\S]*", logcatOut);
+      assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
   }
 
    /**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
index cdeec39..e1c4977 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
@@ -34,8 +34,8 @@
         // Wait for intent to be processed before checking logcat
         Thread.sleep(5000);
         String logcat =  AdbUtils.runCommandLine("logcat -d", getDevice());
-        assertNotMatches("[\\s\\n\\S]*Fatal signal 11 \\(SIGSEGV\\)" +
+        assertNotMatchesMultiLine("Fatal signal 11 \\(SIGSEGV\\)" +
                          "[\\s\\n\\S]*>>> /system/bin/" +
-                         "mediaserver <<<[\\s\\n\\S]*", logcat);
+                         "mediaserver <<<", logcat);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index a4eb539..c9f48f9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -46,7 +46,7 @@
             AdbUtils.runPoc("CVE-2017-13273", getDevice(), 60);
             String dmesgOut = AdbUtils.runCommandLine("cat /sys/fs/pstore/console-ramoops",
                               getDevice());
-            assertNotMatches("[\\s\\n\\S]*CVE-2017-132736 Tainted:" + "[\\s\\n\\S]*" +
+            assertNotMatchesMultiLine("CVE-2017-132736 Tainted:" + "[\\s\\n\\S]*" +
                  "Kernel panic - not syncing: Fatal exception in interrupt", dmesgOut);
         }
         AdbUtils.runCommandLine("setenforce 1",getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
new file mode 100644
index 0000000..02436e7
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.runner.RunWith;
+
+public class Poc18_04 extends SecurityTestCase {
+    /**
+     * b/69683251
+     * Does not require root but must be a hostside test to avoid
+     * a race condition
+     */
+    @SecurityTest(minPatchLevel = "2018-04")
+    public void testPocCVE_2017_13286() throws Exception {
+        LaunchSomeWhere.launchSomeWhere("CVE_2017_13286", getDevice());
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
index 4d8d73b..9595d5a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
@@ -30,6 +30,6 @@
        AdbUtils.runCommandLine("logcat -c" , getDevice());
        AdbUtils.runPoc("CVE-2018-9424", getDevice(), 60);
        String result = AdbUtils.runCommandLine("logcat -d", getDevice());
-       assertNotMatches("[\\s\\n\\S]*Fatal signal [\\s\\n\\S]*", result);
+       assertNotMatchesMultiLine("Fatal signal", result);
      }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java
new file mode 100644
index 0000000..752b06d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.launchanywhere;
+
+import com.android.security.cts.launchanywhere.IGenerateMalformedParcel;
+import android.accounts.AccountManager;
+import android.content.Intent;
+import android.os.Parcel;
+
+public class CVE_2017_13286 implements IGenerateMalformedParcel {
+    @Override
+    public Parcel generate(Intent intent) {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken("android.accounts." +
+                "IAccountAuthenticatorResponse");
+        data.writeInt(1);
+        int bundleLenPos = data.dataPosition();
+        data.writeInt(0xffffffff);
+        data.writeInt(0x4C444E42);
+        int bundleStartPos = data.dataPosition();
+        data.writeInt(3);
+
+        data.writeString("launchanywhere");
+        data.writeInt(4);
+        data.writeString("android.hardware.camera2.params.OutputConfiguration");
+        data.writeInt(0);
+        data.writeInt(1);
+        data.writeInt(2);
+        data.writeInt(3);
+        data.writeInt(4);
+        data.writeInt(5);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(13);
+
+        int byteArrayLenPos = data.dataPosition();
+        data.writeInt(0xffffffff);
+        int byteArrayStartPos = data.dataPosition();
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeInt(0);
+        data.writeString(AccountManager.KEY_INTENT);
+        data.writeInt(4);
+        data.writeString("android.content.Intent");
+        intent.writeToParcel(data, 0);
+        int byteArrayEndPos = data.dataPosition();
+        data.setDataPosition(byteArrayLenPos);
+        int byteArrayLen = byteArrayEndPos - byteArrayStartPos;
+        data.writeInt(byteArrayLen);
+        data.setDataPosition(byteArrayEndPos);
+
+        int bundleEndPos = data.dataPosition();
+        data.setDataPosition(bundleLenPos);
+        int bundleLen = bundleEndPos - bundleStartPos;
+        data.writeInt(bundleLen);
+        data.setDataPosition(bundleEndPos);
+
+        return data;
+    }
+}
diff --git a/hostsidetests/signedconfig/app/Android.mk b/hostsidetests/signedconfig/app/Android.mk
index cc81b6f..1e9b142 100644
--- a/hostsidetests/signedconfig/app/Android.mk
+++ b/hostsidetests/signedconfig/app/Android.mk
@@ -54,3 +54,8 @@
 LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV3_configv1
 LOCAL_MANIFEST_FILE := version3_configv1_AndroidManifest.xml
 include $(LOCAL_PATH)/build_signedconfig_apk.mk
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_debug_key
+LOCAL_MANIFEST_FILE := version1_debug_key_AndroidManifest.xml
+include $(LOCAL_PATH)/build_signedconfig_apk.mk
diff --git a/hostsidetests/signedconfig/app/res/values/strings.xml b/hostsidetests/signedconfig/app/res/values/strings.xml
index e0300b5..454ddc6 100755
--- a/hostsidetests/signedconfig/app/res/values/strings.xml
+++ b/hostsidetests/signedconfig/app/res/values/strings.xml
@@ -15,8 +15,9 @@
 -->
 <resources>
   <string name="signed_config_v1">eyJjb25maWciOiBbeyJ2YWx1ZXMiOiB7ImhpZGRlbl9hcGlfYmxhY2tsaXN0X2V4ZW1wdGlvbnMiOiAiTENsYXNzMTstPm1ldGhvZDEoLExDbGFzczE7LT5maWVsZDE6In0sICJtYXhfc2RrIjogOTksICJtaW5fc2RrIjogMH1dLCAidmVyc2lvbiI6IDF9</string>
-  <string name="signed_config_signature_v1">MEUCIQDtx1a2H/xZV7IonZAGIFWZG3YGFo8AbQKIoL2COqpg9QIgA8aySPWgip3wJjXCCrGGFKViR1lIabbeQZ52QqhLZ/k=</string>
+  <string name="signed_config_signature_v1">MEUCIBx1XVpa8itMVos4oLSzb0zLsWT5mkbjSVrtRO6RnTjFAiEA+wI+G6YdxYdpolPliKXjUE6D0W9iRaqLeD29FZDb3Ic=</string>
+  <string name="signed_config_signature_v1_debug_key">MEQCIF7w8uUCYODYxYXyWvAnlPpLmn6Bv/OsW8fDqKfsGRPrAiA7t0jThzHkayAY841+UfKTA9gOH76Yu0e7BA1v9Fcx4g==</string>
   <string name="signed_config_v2">eyJ2ZXJzaW9uIjogMiwgImNvbmZpZyI6IFt7InZhbHVlcyI6IHsiaGlkZGVuX2FwaV9ibGFja2xpc3RfZXhlbXB0aW9ucyI6ICJMQ2xhc3MyOy0+bWV0aG9kMigsTENsYXNzMjstPmZpZWxkMjoifSwgIm1heF9zZGsiOiA5OSwgIm1pbl9zZGsiOiAwfV19</string>
-  <string name="signed_config_signature_v2">MEYCIQCW4j9khnDoCd7bXuPSw4G3SpNlMirFokO7W75W8HGxAgIhAOJDgSvIApTxoBkZXMhih7kyYxhtMJ777hDCBXR/QAPv</string>
+  <string name="signed_config_signature_v2">MEYCIQCj78TNHymjNlewEYic/yQ9efvwmzRtOVDgW5qhWW6FRwIhAPDiwO2gkoZaBTzIxHGoU2eHDFMb5ydeJjQBuWl/pn+I</string>
   <string name="invalid_b64">invalidb64</string>
 </resources>
diff --git a/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml b/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml
new file mode 100755
index 0000000..7a3462e
--- /dev/null
+++ b/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" ?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.cts.signedconfig.app"
+    android:versionCode="1"
+    android:versionName="1">
+  <application>
+    <meta-data android:name="android.settings.global"
+               android:value="@string/signed_config_v1"/>
+    <meta-data android:name="android.settings.global.signature"
+               android:value="@string/signed_config_signature_v1_debug_key"/>
+  </application>
+</manifest>
diff --git a/hostsidetests/signedconfig/hostside/Android.mk b/hostsidetests/signedconfig/hostside/Android.mk
index fcf3046..b23fb0d 100644
--- a/hostsidetests/signedconfig/hostside/Android.mk
+++ b/hostsidetests/signedconfig/hostside/Android.mk
@@ -45,7 +45,8 @@
     CtsSignedConfigTestAppV1_badsignature \
     CtsSignedConfigTestAppV1_badb64_config \
     CtsSignedConfigTestAppV1_badb64_signature \
-    CtsSignedConfigTestAppV3_configv1
+    CtsSignedConfigTestAppV3_configv1 \
+    CtsSignedConfigTestAppV1_debug_key
 
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
diff --git a/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java b/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
index f68997b..0d57fda 100644
--- a/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
+++ b/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
@@ -54,6 +54,8 @@
             "CtsSignedConfigTestAppV1_badb64_signature.apk";
     private static final String TEST_APP_APK_NAME_V3_CONFIGV1 =
             "CtsSignedConfigTestAppV3_configv1.apk";
+    private static final String TEST_APP_APK_NAME_V1_DEBUG_KEY =
+            "CtsSignedConfigTestAppV1_debug_key.apk";
 
     private static final String SETTING_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
     private static final String SETTING_SIGNED_CONFIG_VERSION = "signed_config_version";
@@ -112,7 +114,6 @@
     public void setUp() throws Exception {
         deleteConfig();
         waitForDevice();
-        Assume.assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
     }
 
     @After
@@ -213,4 +214,24 @@
         assertThat(getDevice().getSetting("global", SETTING_SIGNED_CONFIG_VERSION))
                 .isEqualTo("null");
     }
+
+    @Test
+    public void testDebugKeyValidOnDebugBuild() throws Exception {
+        Assume.assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
+        installPackage(TEST_APP_APK_NAME_V1_DEBUG_KEY);
+        waitUntilSettingMatches(SETTING_SIGNED_CONFIG_VERSION, "1");
+        assertThat(getDevice().getSetting("global", SETTING_BLACKLIST_EXEMPTIONS)).isEqualTo(
+                "LClass1;->method1(,LClass1;->field1:");
+    }
+
+    @Test
+    public void testDebugKeyNotValidOnUserBuild() throws Exception {
+        Assume.assumeThat(getDevice().getBuildFlavor(), endsWith("-user"));
+        installPackage(TEST_APP_APK_NAME_V1_DEBUG_KEY);
+        waitForDevice(5);
+        assertThat(getDevice().getSetting("global", SETTING_SIGNED_CONFIG_VERSION))
+                .isEqualTo("null");
+        assertThat(getDevice().getSetting("global", SETTING_BLACKLIST_EXEMPTIONS))
+                .isEqualTo("null");
+    }
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index e9996f1..8d5e523 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -417,6 +417,29 @@
         assertTrue(atom.getBatteryLevel().getBatteryLevel() <= 100);
     }
 
+    // This test is for the pulled battery charge count atom.
+    public void testBatteryCycleCount() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+        if (!hasFeature(FEATURE_WATCH, false)) return;
+        StatsdConfig.Builder config = getPulledConfig();
+        addGaugeAtomWithDimensions(config, Atom.BATTERY_CYCLE_COUNT_FIELD_NUMBER, null);
+
+        uploadConfig(config);
+
+        Thread.sleep(WAIT_TIME_LONG);
+        setAppBreadcrumbPredicate();
+        Thread.sleep(WAIT_TIME_LONG);
+
+        List<Atom> data = getGaugeMetricDataList();
+
+        assertTrue(data.size() > 0);
+        Atom atom = data.get(0);
+        assertTrue(atom.getBatteryCycleCount().hasCycleCount());
+        assertTrue(atom.getBatteryCycleCount().getCycleCount() > 0);
+    }
+
     public void testKernelWakelock() throws Exception {
         if (statsdDisabled() || !kernelWakelockStatsExist()) {
             return;
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
index 6a3c4a3..cfa0a37 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
@@ -390,6 +390,8 @@
         Thread.sleep(WAIT_TIME_SHORT);
 
         List<Atom> statsdData = getGaugeMetricDataList();
+        assertTrue(statsdData.size() > 0);
+        assertTrue(statsdData.get(0).getProcStatsPkgProc().getProcStatsSection().getAvailablePagesList().size() > 0);
 
         List<ProcessStatsPackageProto> processStatsPackageProtoList = getAllProcStatsProto();
 
diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml
index bb62742..9a8b7b2 100755
--- a/hostsidetests/theme/app/AndroidManifest.xml
+++ b/hostsidetests/theme/app/AndroidManifest.xml
@@ -18,7 +18,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.theme.app">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application>
@@ -32,7 +31,7 @@
         </activity>
         <activity android:name=".GenerateImagesActivity"
                   android:screenOrientation="portrait"
-                  android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
+                  android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|uiMode"
                   android:exported="true" />
     </application>
 
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
index 1bf4da1..3591410 100644
--- a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
@@ -27,12 +27,16 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.util.Log;
+import android.util.Pair;
 import android.view.WindowManager.LayoutParams;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 /**
  * Generates images by iterating through all themes and launching instances of
@@ -59,63 +63,65 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
-                | LayoutParams.FLAG_TURN_SCREEN_ON
-                | LayoutParams.FLAG_DISMISS_KEYGUARD);
+        // Useful for local testing. Not required for CTS harness.
+        getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
 
+        mOutputDir = setupOutputDirectory();
+        if (mOutputDir == null) {
+            finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
+        }
+
+        // The activity has been created, but we don't want to start image generation until various
+        // asynchronous conditions are satisfied.
+        new ConditionCheck(this, () -> generateNextImage(), message -> finish(message, false))
+                .addCondition("Device is unlocked",
+                        () -> !getSystemService(KeyguardManager.class).isDeviceLocked())
+                .addCondition("Window is focused",
+                        () -> hasWindowFocus())
+                .start();
+    }
+
+    private File setupOutputDirectory() {
         mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR);
         ThemeTestUtils.deleteDirectory(mOutputDir);
         mOutputDir.mkdirs();
 
-        if (!mOutputDir.exists()) {
-            finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
-            return;
+        if (mOutputDir.exists()) {
+            return mOutputDir;
         }
-
-        final boolean canDisableKeyguard = checkCallingOrSelfPermission(
-                permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED;
-        if (!canDisableKeyguard) {
-            finish("Not granted permission to disable keyguard", false);
-            return;
-        }
-
-        new KeyguardCheck(this) {
-            @Override
-            public void onSuccess() {
-                generateNextImage();
-            }
-
-            @Override
-            public void onFailure() {
-                finish("Device is locked", false);
-            }
-        }.start();
+        return null;
     }
 
-    public boolean isFinishSuccess() {
-        return mFinishSuccess;
-    }
-
-    public String getFinishReason() {
-        return mFinishReason;
-    }
-
-    static abstract class KeyguardCheck implements Runnable {
+    /**
+     * Runnable that re-posts itself on a handler until either all of the conditions are satisfied
+     * or a retry threshold is exceeded.
+     */
+    class ConditionCheck implements Runnable {
         private static final int MAX_RETRIES = 3;
         private static final int RETRY_DELAY = 500;
 
         private final Handler mHandler;
-        private final KeyguardManager mKeyguard;
+        private final Runnable mOnSuccess;
+        private final Consumer<String> mOnFailure;
+        private final ArrayList<Pair<String, Supplier<Boolean>>> mConditions = new ArrayList<>();
 
-        private int mRetries;
+        private ArrayList<Pair<String, Supplier<Boolean>>> mRemainingConditions = new ArrayList<>();
+        private int mRemainingRetries;
 
-        public KeyguardCheck(Context context) {
+        ConditionCheck(Context context, Runnable onSuccess, Consumer<String> onFailure) {
             mHandler = new Handler(context.getMainLooper());
-            mKeyguard = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
+            mOnSuccess = onSuccess;
+            mOnFailure = onFailure;
+        }
+
+        public ConditionCheck addCondition(String summary, Supplier<Boolean> condition) {
+            mConditions.add(new Pair<>(summary, condition));
+            return this;
         }
 
         public void start() {
-            mRetries = 0;
+            mRemainingConditions = new ArrayList<>(mConditions);
+            mRemainingRetries = 0;
 
             mHandler.removeCallbacks(this);
             mHandler.post(this);
@@ -127,19 +133,35 @@
 
         @Override
         public void run() {
-            if (!mKeyguard.isKeyguardLocked()) {
-                onSuccess();
-            } else if (mRetries < MAX_RETRIES) {
-                mRetries++;
+            mRemainingConditions.removeIf(condition -> condition.second.get());
+            if (mRemainingConditions.isEmpty()) {
+                mOnSuccess.run();
+            } else if (mRemainingRetries < MAX_RETRIES) {
+                mRemainingRetries++;
+                mHandler.removeCallbacks(this);
                 mHandler.postDelayed(this, RETRY_DELAY);
             } else {
-                onFailure();
+                final StringBuffer buffer = new StringBuffer("Failed conditions:");
+                mRemainingConditions.forEach(condition ->
+                        buffer.append("\n").append(condition.first));
+                mOnFailure.accept(buffer.toString());
             }
-
         }
+    }
 
-        public abstract void onSuccess();
-        public abstract void onFailure();
+    /**
+     * @return whether the test finished successfully
+     */
+    public boolean isFinishSuccess() {
+        return mFinishSuccess;
+    }
+
+    /**
+     * @return user-visible string explaining why the test finished, may be {@code null} if the test
+     *         finished unexpectedly
+     */
+    public String getFinishReason() {
+        return mFinishReason;
     }
 
     /**
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index bf113ff..80a8964 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -31,8 +31,9 @@
 import android.webkit.SslErrorHandler;
 import android.webkit.WebView;
 import android.webkit.cts.CtsTestServer;
-import android.webkit.cts.WebViewOnUiThread;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebkitUtils;
 import android.webkit.WebView;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
@@ -100,16 +101,16 @@
         // Now create WebView and test that setting the cookie beforehand really worked.
         mActivity.createAndAttachWebView();
         WebView webView = mActivity.getWebView();
-        WebViewOnUiThread onUiThread = new WebViewOnUiThread(mActivity.getWebView());
-        webView.setWebViewClient(new WaitForLoadedClient(onUiThread) {
+        WebViewSyncLoader syncLoader = new WebViewSyncLoader(webView);
+        webView.setWebViewClient(new WaitForLoadedClient(syncLoader) {
             @Override
             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                 // Not intended to verify server certificate, ignore the error.
                 if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) handler.proceed();
             }
         });
-        onUiThread.loadUrlAndWaitForCompletion(url);
-        assertEquals("1|count=41", onUiThread.getTitle()); // outgoing cookie
+        syncLoader.loadUrlAndWaitForCompletion(url);
+        assertEquals("1|count=41", webView.getTitle()); // outgoing cookie
         CookieManager cookieManager = CookieManager.getInstance();
         String cookie = cookieManager.getCookie(url);
         assertNotNull(cookie);
@@ -117,6 +118,7 @@
         Matcher m = pat.matcher(cookie);
         assertTrue(m.matches());
         assertEquals("42", m.group(1)); // value got incremented
+        syncLoader.detach();
     }
 
     @UiThreadTest
@@ -140,11 +142,8 @@
             if (alreadyOnMainThread) {
                 mActivity.createAndAttachWebView();
             } else {
-                getInstrumentation().runOnMainSync(new Runnable() {
-                    @Override
-                    public void run() {
-                        mActivity.createAndAttachWebView();
-                    }
+                WebkitUtils.onMainThreadSync(() -> {
+                    mActivity.createAndAttachWebView();
                 });
             }
 
@@ -211,9 +210,10 @@
         // WebView is available, so try to call some WebView APIs to ensure they don't cause
         // strictmode violations
 
-        WebViewOnUiThread onUiThread = new WebViewOnUiThread(mActivity.getWebView());
-        onUiThread.loadUrlAndWaitForCompletion("about:blank");
-        onUiThread.loadUrlAndWaitForCompletion("");
+        WebViewSyncLoader syncLoader = new WebViewSyncLoader(mActivity.getWebView());
+        syncLoader.loadUrlAndWaitForCompletion("about:blank");
+        syncLoader.loadUrlAndWaitForCompletion("");
+        syncLoader.detach();
     }
 
     @UiThreadTest
@@ -232,16 +232,12 @@
         PackageManager pm = mActivity.getPackageManager();
         if (!pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) return;
 
-        WebView[] webviewHolder = new WebView[1];
         // Create the WebView on the UI thread and then ensure webview.getWebViewLooper() returns
         // the UI thread.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                webviewHolder[0] = createAndCheckWebViewLooper();
-            }
+        WebView webView = WebkitUtils.onMainThreadSync(() -> {
+            return createAndCheckWebViewLooper();
         });
-        assertEquals(Looper.getMainLooper(), webviewHolder[0].getWebViewLooper());
+        assertEquals(Looper.getMainLooper(), webView.getWebViewLooper());
     }
 
     /**
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
index dbe7439..217e3d3 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
@@ -21,11 +21,8 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.net.http.SslCertificate;
-import android.os.Looper;
 import android.os.Message;
-import android.os.SystemClock;
 import android.print.PrintDocumentAdapter;
-import android.support.test.rule.ActivityTestRule;
 import android.util.DisplayMetrics;
 import android.view.View;
 import android.view.ViewGroup;
@@ -48,10 +45,6 @@
 
 import com.google.common.util.concurrent.SettableFuture;
 
-import junit.framework.Assert;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 
 /**
@@ -64,107 +57,27 @@
  * Modifications to this class should be reflected in that class as necessary. See
  * http://go/modifying-webview-cts.
  */
-public class WebViewOnUiThread {
-    /**
-     * The maximum time, in milliseconds (10 seconds) to wait for a load
-     * to be triggered.
-     */
-    private static final long LOAD_TIMEOUT = 10000;
-
-    /**
-     * Set to true after onPageFinished is called.
-     */
-    private boolean mLoaded;
-
-    /**
-     * Set to true after onNewPicture is called. Reset when onPageStarted
-     * is called.
-     */
-    private boolean mNewPicture;
-
-    /**
-     * The progress, in percentage, of the page load. Valid values are between
-     * 0 and 100.
-     */
-    private int mProgress;
-
+public class WebViewOnUiThread extends WebViewSyncLoader {
     /**
      * The WebView that calls will be made on.
      */
     private WebView mWebView;
 
     /**
-     * Initializes the webView with a WebViewClient, WebChromeClient,
-     * and PictureListener to prepare for loadUrlAndWaitForCompletion.
+     * Wraps a WebView to ensure that methods are run on the UI thread.
      *
      * A new WebViewOnUiThread should be called during setUp so as to
      * reinitialize between calls.
      *
-     * @param test The test in which this is being run.
      * @param webView The webView that the methods should call.
-     * @see #loadDataAndWaitForCompletion(String, String, String)
-     * @deprecated Use {@link WebViewOnUiThread#WebViewOnUiThread(ActivityTestRule, WebView)}
      */
-    @Deprecated
     public WebViewOnUiThread(WebView webView) {
+        super(webView);
         mWebView = webView;
-        final WebViewClient webViewClient = new WaitForLoadedClient(this);
-        final WebChromeClient webChromeClient = new WaitForProgressClient(this);
-        WebkitUtils.onMainThreadSync(() -> {
-            mWebView.setWebViewClient(webViewClient);
-            mWebView.setWebChromeClient(webChromeClient);
-            mWebView.setPictureListener(new WaitForNewPicture());
-        });
     }
 
-    /**
-     * Called after a test is complete and the WebView should be disengaged from
-     * the tests.
-     */
     public void cleanUp() {
-        WebkitUtils.onMainThreadSync(() -> {
-            mWebView.clearHistory();
-            mWebView.clearCache(true);
-            mWebView.setWebChromeClient(null);
-            mWebView.setWebViewClient(null);
-            mWebView.destroy();
-        });
-    }
-
-    /**
-     * Called from WaitForNewPicture, this is used to indicate that
-     * the page has been drawn.
-     */
-    synchronized public void onNewPicture() {
-        mNewPicture = true;
-        this.notifyAll();
-    }
-
-    /**
-     * Called from WaitForLoadedClient, this is used to clear the picture
-     * draw state so that draws before the URL begins loading don't count.
-     */
-    synchronized public void onPageStarted() {
-        mNewPicture = false; // Earlier paints won't count.
-    }
-
-    /**
-     * Called from WaitForLoadedClient, this is used to indicate that
-     * the page is loaded, but not drawn yet.
-     */
-    synchronized public void onPageFinished() {
-        mLoaded = true;
-        this.notifyAll();
-    }
-
-    /**
-     * Called from the WebChrome client, this sets the current progress
-     * for a page.
-     * @param progress The progress made so far between 0 and 100.
-     */
-    synchronized public void onProgressChanged(int progress) {
-        mProgress = progress;
-        this.notifyAll();
+        super.destroy();
     }
 
     public void setWebViewClient(final WebViewClient webViewClient) {
@@ -216,7 +129,7 @@
     }
 
     public void requestFocus() {
-        new PollingCheck(LOAD_TIMEOUT) {
+        new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
             @Override
             protected boolean check() {
                 requestFocusOnUiThread();
@@ -351,38 +264,6 @@
         });
     }
 
-    /**
-     * Calls loadUrl on the WebView and then waits onPageFinished,
-     * onNewPicture and onProgressChange to reach 100.
-     * Test fails if the load timeout elapses.
-     * @param url The URL to load.
-     */
-    public void loadUrlAndWaitForCompletion(final String url) {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.loadUrl(url);
-            }
-        });
-    }
-
-    /**
-     * Calls loadUrl on the WebView and then waits onPageFinished,
-     * onNewPicture and onProgressChange to reach 100.
-     * Test fails if the load timeout elapses.
-     * @param url The URL to load.
-     * @param extraHeaders The additional headers to be used in the HTTP request.
-     */
-    public void loadUrlAndWaitForCompletion(final String url,
-            final Map<String, String> extraHeaders) {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.loadUrl(url, extraHeaders);
-            }
-        });
-    }
-
     public void loadUrl(final String url) {
         WebkitUtils.onMainThreadSync(() -> {
             mWebView.loadUrl(url);
@@ -395,55 +276,8 @@
         });
     }
 
-    public void postUrlAndWaitForCompletion(final String url, final byte[] postData) {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.postUrl(url, postData);
-            }
-        });
-    }
-
-    public void loadDataAndWaitForCompletion(final String data,
-            final String mimeType, final String encoding) {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.loadData(data, mimeType, encoding);
-            }
-        });
-    }
-
-    public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
-            final String data, final String mimeType, final String encoding,
-            final String historyUrl) {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding,
-                        historyUrl);
-            }
-        });
-    }
-
     /**
-     * Reloads a page and waits for it to complete reloading. Use reload
-     * if it is a form resubmission and the onFormResubmission responds
-     * by telling WebView not to resubmit it.
-     */
-    public void reloadAndWaitForCompletion() {
-        callAndWait(new Runnable() {
-            @Override
-            public void run() {
-                mWebView.reload();
-            }
-        });
-    }
-
-    /**
-     * Reload the previous URL. Use reloadAndWaitForCompletion unless
-     * it is a form resubmission and the onFormResubmission responds
-     * by telling WebView not to resubmit it.
+     * Reload the previous URL.
      */
     public void reload() {
         WebkitUtils.onMainThreadSync(() -> {
@@ -451,30 +285,6 @@
         });
     }
 
-    /**
-     * Use this only when JavaScript causes a page load to wait for the
-     * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
-     * similar functions.
-     */
-    public void waitForLoadCompletion() {
-        waitForCriteria(LOAD_TIMEOUT,
-                new Callable<Boolean>() {
-                    @Override
-                    public Boolean call() {
-                        return isLoaded();
-                    }
-                });
-        clearLoad();
-    }
-
-    private void waitForCriteria(long timeout, Callable<Boolean> doneCriteria) {
-        if (isUiThread()) {
-            waitOnUiThread(timeout, doneCriteria);
-        } else {
-            waitOnTestThread(timeout, doneCriteria);
-        }
-    }
-
     public String getTitle() {
         return WebkitUtils.onMainThreadSync(() -> {
             return mWebView.getTitle();
@@ -695,116 +505,6 @@
     }
 
     /**
-     * Returns true if the current thread is the UI thread based on the
-     * Looper.
-     */
-    private static boolean isUiThread() {
-        return (Looper.myLooper() == Looper.getMainLooper());
-    }
-
-    /**
-     * @return Whether or not the load has finished.
-     */
-    private synchronized boolean isLoaded() {
-        return mLoaded && mNewPicture && mProgress == 100;
-    }
-
-    /**
-     * Makes a WebView call, waits for completion and then resets the
-     * load state in preparation for the next load call.
-     *
-     * <p>This method may be called on the UI thread.
-     *
-     * @param call The call to make on the UI thread prior to waiting.
-     */
-    private void callAndWait(Runnable call) {
-        Assert.assertTrue("WebViewOnUiThread.load*AndWaitForCompletion calls "
-                + "may not be mixed with load* calls directly on WebView "
-                + "without calling waitForLoadCompletion after the load",
-                !isLoaded());
-        clearLoad(); // clear any extraneous signals from a previous load.
-        if (isUiThread()) {
-            call.run();
-        } else {
-            WebkitUtils.onMainThread(call);
-        }
-        waitForLoadCompletion();
-    }
-
-    /**
-     * Called whenever a load has been completed so that a subsequent call to
-     * waitForLoadCompletion doesn't return immediately.
-     */
-    synchronized private void clearLoad() {
-        mLoaded = false;
-        mNewPicture = false;
-        mProgress = 0;
-    }
-
-    /**
-     * Uses a polling mechanism, while pumping messages to check when the
-     * criteria is met.
-     */
-    private void waitOnUiThread(long timeout, final Callable<Boolean> doneCriteria) {
-        new PollingCheck(timeout) {
-            @Override
-            protected boolean check() {
-                pumpMessages();
-                try {
-                    return doneCriteria.call();
-                } catch (Exception e) {
-                    Assert.fail("Unexpected error while checking the criteria: "
-                            + e.getMessage());
-                    return true;
-                }
-            }
-        }.run();
-    }
-
-    /**
-     * Uses a wait/notify to check when the criteria is met.
-     */
-    private synchronized void waitOnTestThread(long timeout, Callable<Boolean> doneCriteria) {
-        try {
-            long waitEnd = SystemClock.uptimeMillis() + timeout;
-            long timeRemaining = timeout;
-            while (!doneCriteria.call() && timeRemaining > 0) {
-                this.wait(timeRemaining);
-                timeRemaining = waitEnd - SystemClock.uptimeMillis();
-            }
-            Assert.assertTrue("Action failed to complete before timeout", doneCriteria.call());
-        } catch (InterruptedException e) {
-            // We'll just drop out of the loop and fail
-        } catch (Exception e) {
-            Assert.fail("Unexpected error while checking the criteria: "
-                    + e.getMessage());
-        }
-    }
-
-    /**
-     * Pumps all currently-queued messages in the UI thread and then exits.
-     * This is useful to force processing while running tests in the UI thread.
-     */
-    private void pumpMessages() {
-        class ExitLoopException extends RuntimeException {
-        }
-
-        // Force loop to exit when processing this. Loop.quit() doesn't
-        // work because this is the main Loop.
-        mWebView.getHandler().post(new Runnable() {
-            @Override
-            public void run() {
-                throw new ExitLoopException(); // exit loop!
-            }
-        });
-        try {
-            // Pump messages until our message gets through.
-            Looper.loop();
-        } catch (ExitLoopException e) {
-        }
-    }
-
-    /**
      * Set LayoutParams to MATCH_PARENT.
      *
      * @param view Target view
@@ -815,65 +515,4 @@
         params.width = ViewGroup.LayoutParams.MATCH_PARENT;
         view.setLayoutParams(params);
     }
-
-    /**
-     * A WebChromeClient used to capture the onProgressChanged for use
-     * in waitFor functions. If a test must override the WebChromeClient,
-     * it can derive from this class or call onProgressChanged
-     * directly.
-     */
-    public static class WaitForProgressClient extends WebChromeClient {
-        private WebViewOnUiThread mOnUiThread;
-
-        public WaitForProgressClient(WebViewOnUiThread onUiThread) {
-            mOnUiThread = onUiThread;
-        }
-
-        @Override
-        public void onProgressChanged(WebView view, int newProgress) {
-            super.onProgressChanged(view, newProgress);
-            mOnUiThread.onProgressChanged(newProgress);
-        }
-    }
-
-    /**
-     * A WebViewClient that captures the onPageFinished for use in
-     * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
-     * into the WebView. If a test needs to set a specific WebViewClient and
-     * needs the waitForCompletion capability then it should derive from
-     * WaitForLoadedClient or call WebViewOnUiThread.onPageFinished.
-     */
-    public static class WaitForLoadedClient extends WebViewClient {
-        private WebViewOnUiThread mOnUiThread;
-
-        public WaitForLoadedClient(WebViewOnUiThread onUiThread) {
-            mOnUiThread = onUiThread;
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            super.onPageFinished(view, url);
-            mOnUiThread.onPageFinished();
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            super.onPageStarted(view, url, favicon);
-            mOnUiThread.onPageStarted();
-        }
-    }
-
-    /**
-     * A PictureListener that captures the onNewPicture for use in
-     * waitForLoadCompletion. Using initializeWebView sets the PictureListener
-     * into the WebView. If a test needs to set a specific PictureListener and
-     * needs the waitForCompletion capability then it should call
-     * WebViewOnUiThread.onNewPicture.
-     */
-    private class WaitForNewPicture implements PictureListener {
-        @Override
-        public void onNewPicture(WebView view, Picture picture) {
-            WebViewOnUiThread.this.onNewPicture();
-        }
-    }
 }
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java
new file mode 100644
index 0000000..2b27b52
--- /dev/null
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2011 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.webkit.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Picture;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.webkit.WebChromeClient;
+import android.webkit.WebView;
+import android.webkit.WebView.PictureListener;
+import android.webkit.WebViewClient;
+
+import androidx.annotation.CallSuper;
+
+import com.android.compatibility.common.util.PollingCheck;
+
+import junit.framework.Assert;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Utility class to simplify tests that need to load data into a WebView and wait for completion
+ * conditions.
+ *
+ * May be used from any thread.
+ */
+public class WebViewSyncLoader {
+    /**
+     * Set to true after onPageFinished is called.
+     */
+    private boolean mLoaded;
+
+    /**
+     * Set to true after onNewPicture is called. Reset when onPageStarted
+     * is called.
+     */
+    private boolean mNewPicture;
+
+    /**
+     * The progress, in percentage, of the page load. Valid values are between
+     * 0 and 100.
+     */
+    private int mProgress;
+
+    /**
+     * The WebView that calls will be made on.
+     */
+    private WebView mWebView;
+
+
+    public WebViewSyncLoader(WebView webView) {
+        init(webView, new WaitForLoadedClient(this), new WaitForProgressClient(this),
+                new WaitForNewPicture(this));
+    }
+
+    public WebViewSyncLoader(
+            WebView webView,
+            WaitForLoadedClient waitForLoadedClient,
+            WaitForProgressClient waitForProgressClient,
+            WaitForNewPicture waitForNewPicture) {
+        init(webView, waitForLoadedClient, waitForProgressClient, waitForNewPicture);
+    }
+
+    private void init(
+            final WebView webView,
+            final WaitForLoadedClient waitForLoadedClient,
+            final WaitForProgressClient waitForProgressClient,
+            final WaitForNewPicture waitForNewPicture) {
+        if (!isUiThread()) {
+            WebkitUtils.onMainThreadSync(() -> {
+                init(webView, waitForLoadedClient, waitForProgressClient, waitForNewPicture);
+            });
+            return;
+        }
+        mWebView = webView;
+        mWebView.setWebViewClient(waitForLoadedClient);
+        mWebView.setWebChromeClient(waitForProgressClient);
+        mWebView.setPictureListener(waitForNewPicture);
+    }
+
+    /**
+     * Detach listeners from this WebView, undoing the changes made to enable sync loading.
+     */
+    public void detach() {
+        if (!isUiThread()) {
+            WebkitUtils.onMainThreadSync(this::detach);
+            return;
+        }
+        mWebView.setWebChromeClient(null);
+        mWebView.setWebViewClient(null);
+        mWebView.setPictureListener(null);
+        mWebView = null;
+    }
+
+    /**
+     * Detach listeners, and destroy this webview.
+     */
+    public void destroy() {
+        if (!isUiThread()) {
+            WebkitUtils.onMainThreadSync(this::destroy);
+            return;
+        }
+        WebView webView = mWebView;
+        detach();
+        webView.clearHistory();
+        webView.clearCache(true);
+        webView.destroy();
+    }
+
+    /**
+     * Accessor for underlying WebView.
+     * @return The WebView being wrapped by this class.
+     */
+    public WebView getWebView() {
+        return mWebView;
+    }
+
+    /**
+     * Called from WaitForNewPicture, this is used to indicate that
+     * the page has been drawn.
+     */
+    public synchronized void onNewPicture() {
+        mNewPicture = true;
+        this.notifyAll();
+    }
+
+    /**
+     * Called from WaitForLoadedClient, this is used to clear the picture
+     * draw state so that draws before the URL begins loading don't count.
+     */
+    public synchronized void onPageStarted() {
+        mNewPicture = false; // Earlier paints won't count.
+    }
+
+    /**
+     * Called from WaitForLoadedClient, this is used to indicate that
+     * the page is loaded, but not drawn yet.
+     */
+    public synchronized void onPageFinished() {
+        mLoaded = true;
+        this.notifyAll();
+    }
+
+    /**
+     * Called from the WebChrome client, this sets the current progress
+     * for a page.
+     * @param progress The progress made so far between 0 and 100.
+     */
+    public synchronized void onProgressChanged(int progress) {
+        mProgress = progress;
+        this.notifyAll();
+    }
+
+    /**
+     * Calls {@link WebView#loadUrl} on the WebView and then waits for completion.
+     *
+     * <p>Test fails if the load timeout elapses.
+     */
+    public void loadUrlAndWaitForCompletion(final String url) {
+        callAndWait(() -> mWebView.loadUrl(url));
+    }
+
+    /**
+     * Calls {@link WebView#loadUrl(String,Map<String,String>)} on the WebView and waits for
+     * completion.
+     *
+     * <p>Test fails if the load timeout elapses.
+     */
+    public void loadUrlAndWaitForCompletion(final String url,
+            final Map<String, String> extraHeaders) {
+        callAndWait(() -> mWebView.loadUrl(url, extraHeaders));
+    }
+
+    /**
+     * Calls {@link WebView#postUrl(String,byte[])} on the WebView and then waits for completion.
+     *
+     * <p>Test fails if the load timeout elapses.
+     *
+     * @param url The URL to load.
+     * @param postData the data will be passed to "POST" request.
+     */
+    public void postUrlAndWaitForCompletion(final String url, final byte[] postData) {
+        callAndWait(() -> mWebView.postUrl(url, postData));
+    }
+
+    /**
+     * Calls {@link WebView#loadData(String,String,String)} on the WebView and then waits for
+     * completion.
+     *
+     * <p>Test fails if the load timeout elapses.
+     */
+    public void loadDataAndWaitForCompletion(final String data,
+            final String mimeType, final String encoding) {
+        callAndWait(() -> mWebView.loadData(data, mimeType, encoding));
+    }
+
+    /**
+     * Calls {@link WebView#loadDataWithBaseUrl(String,String,String,String,String)} on the WebView
+     * and then waits for completion.
+     *
+     * <p>Test fails if the load timeout elapses.
+     */
+    public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
+            final String data, final String mimeType, final String encoding,
+            final String historyUrl) {
+        callAndWait(
+                () -> mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl));
+    }
+
+    /**
+     * Reloads a page and waits for it to complete reloading. Use reload
+     * if it is a form resubmission and the onFormResubmission responds
+     * by telling WebView not to resubmit it.
+     */
+    public void reloadAndWaitForCompletion() {
+        callAndWait(() -> mWebView.reload());
+    }
+
+    /**
+     * Use this only when JavaScript causes a page load to wait for the
+     * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
+     * similar functions.
+     */
+    public void waitForLoadCompletion() {
+        waitForCriteria(WebkitUtils.TEST_TIMEOUT_MS,
+                new Callable<Boolean>() {
+                    @Override
+                    public Boolean call() {
+                        return isLoaded();
+                    }
+                });
+        clearLoad();
+    }
+
+    private void waitForCriteria(long timeout, Callable<Boolean> doneCriteria) {
+        if (isUiThread()) {
+            waitOnUiThread(timeout, doneCriteria);
+        } else {
+            waitOnTestThread(timeout, doneCriteria);
+        }
+    }
+
+    /**
+     * @return Whether or not the load has finished.
+     */
+    private synchronized boolean isLoaded() {
+        return mLoaded && mNewPicture && mProgress == 100;
+    }
+
+    /**
+     * Makes a WebView call, waits for completion and then resets the
+     * load state in preparation for the next load call.
+     *
+     * <p>This method may be called on the UI thread.
+     *
+     * @param call The call to make on the UI thread prior to waiting.
+     */
+    private void callAndWait(Runnable call) {
+        Assert.assertTrue("WebViewSyncLoader.load*AndWaitForCompletion calls "
+                + "may not be mixed with load* calls directly on WebView "
+                + "without calling waitForLoadCompletion after the load",
+                !isLoaded());
+        clearLoad(); // clear any extraneous signals from a previous load.
+        if (isUiThread()) {
+            call.run();
+        } else {
+            WebkitUtils.onMainThread(call);
+        }
+        waitForLoadCompletion();
+    }
+
+    /**
+     * Called whenever a load has been completed so that a subsequent call to
+     * waitForLoadCompletion doesn't return immediately.
+     */
+    private synchronized void clearLoad() {
+        mLoaded = false;
+        mNewPicture = false;
+        mProgress = 0;
+    }
+
+    /**
+     * Uses a polling mechanism, while pumping messages to check when the
+     * criteria is met.
+     */
+    private void waitOnUiThread(long timeout, final Callable<Boolean> doneCriteria) {
+        new PollingCheck(timeout) {
+            @Override
+            protected boolean check() {
+                pumpMessages();
+                try {
+                    return doneCriteria.call();
+                } catch (Exception e) {
+                    Assert.fail("Unexpected error while checking the criteria: "
+                            + e.getMessage());
+                    return true;
+                }
+            }
+        }.run();
+    }
+
+    /**
+     * Uses a wait/notify to check when the criteria is met.
+     */
+    private synchronized void waitOnTestThread(long timeout, Callable<Boolean> doneCriteria) {
+        try {
+            long waitEnd = SystemClock.uptimeMillis() + timeout;
+            long timeRemaining = timeout;
+            while (!doneCriteria.call() && timeRemaining > 0) {
+                this.wait(timeRemaining);
+                timeRemaining = waitEnd - SystemClock.uptimeMillis();
+            }
+            Assert.assertTrue("Action failed to complete before timeout", doneCriteria.call());
+        } catch (InterruptedException e) {
+            // We'll just drop out of the loop and fail
+        } catch (Exception e) {
+            Assert.fail("Unexpected error while checking the criteria: "
+                    + e.getMessage());
+        }
+    }
+
+    /**
+     * Pumps all currently-queued messages in the UI thread and then exits.
+     * This is useful to force processing while running tests in the UI thread.
+     */
+    private void pumpMessages() {
+        class ExitLoopException extends RuntimeException {
+        }
+
+        // Force loop to exit when processing this. Loop.quit() doesn't
+        // work because this is the main Loop.
+        mWebView.getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                throw new ExitLoopException(); // exit loop!
+            }
+        });
+        try {
+            // Pump messages until our message gets through.
+            Looper.loop();
+        } catch (ExitLoopException e) {
+        }
+    }
+
+    /**
+     * Returns true if the current thread is the UI thread based on the
+     * Looper.
+     */
+    private static boolean isUiThread() {
+        return (Looper.myLooper() == Looper.getMainLooper());
+    }
+
+    /**
+     * A WebChromeClient used to capture the onProgressChanged for use
+     * in waitFor functions. If a test must override the WebChromeClient,
+     * it can derive from this class or call onProgressChanged
+     * directly.
+     */
+    public static class WaitForProgressClient extends WebChromeClient {
+        private WebViewSyncLoader mWebViewSyncLoader;
+
+        public WaitForProgressClient(WebViewSyncLoader webViewSyncLoader) {
+            mWebViewSyncLoader = webViewSyncLoader;
+        }
+
+        @Override
+        @CallSuper
+        public void onProgressChanged(WebView view, int newProgress) {
+            super.onProgressChanged(view, newProgress);
+            mWebViewSyncLoader.onProgressChanged(newProgress);
+        }
+    }
+
+    /**
+     * A WebViewClient that captures the onPageFinished for use in
+     * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
+     * into the WebView. If a test needs to set a specific WebViewClient and
+     * needs the waitForCompletion capability then it should derive from
+     * WaitForLoadedClient or call WebViewSyncLoader.onPageFinished.
+     */
+    public static class WaitForLoadedClient extends WebViewClient {
+        private WebViewSyncLoader mWebViewSyncLoader;
+
+        public WaitForLoadedClient(WebViewSyncLoader webViewSyncLoader) {
+            mWebViewSyncLoader = webViewSyncLoader;
+        }
+
+        @Override
+        @CallSuper
+        public void onPageFinished(WebView view, String url) {
+            super.onPageFinished(view, url);
+            mWebViewSyncLoader.onPageFinished();
+        }
+
+        @Override
+        @CallSuper
+        public void onPageStarted(WebView view, String url, Bitmap favicon) {
+            super.onPageStarted(view, url, favicon);
+            mWebViewSyncLoader.onPageStarted();
+        }
+    }
+
+    /**
+     * A PictureListener that captures the onNewPicture for use in
+     * waitForLoadCompletion. Using initializeWebView sets the PictureListener
+     * into the WebView. If a test needs to set a specific PictureListener and
+     * needs the waitForCompletion capability then it should call
+     * WebViewSyncLoader.onNewPicture.
+     */
+    public static class WaitForNewPicture implements PictureListener {
+        private WebViewSyncLoader mWebViewSyncLoader;
+
+        public WaitForNewPicture(WebViewSyncLoader webViewSyncLoader) {
+            mWebViewSyncLoader = webViewSyncLoader;
+        }
+
+        @Override
+        @CallSuper
+        public void onNewPicture(WebView view, Picture picture) {
+            mWebViewSyncLoader.onNewPicture();
+        }
+    }
+}
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java b/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
index 419c633..eb9bdaa 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
@@ -38,7 +38,15 @@
  */
 public final class WebkitUtils {
 
-    private static final long TEST_TIMEOUT_MS = 20000L; // 20s.
+    /**
+     * Arbitrary timeout for tests. This is intended to be used with {@link TimeUnit#MILLISECONDS}
+     * so that this can represent 20 seconds.
+     *
+     * <p class=note><b>Note:</b> only use this timeout value for the unexpected case, not for the
+     * correct case, as this exceeds the time recommendation for {@link
+     * androidx.test.filters.MediumTest}.
+     */
+    public static final long TEST_TIMEOUT_MS = 20000L; // 20s.
 
     // A handler for the main thread.
     private static final Handler sMainHandler = new Handler(Looper.getMainLooper());
diff --git a/suite/audio_quality/lib/src/task/TaskGeneric.cpp b/suite/audio_quality/lib/src/task/TaskGeneric.cpp
index c0e4935..4a394e2 100644
--- a/suite/audio_quality/lib/src/task/TaskGeneric.cpp
+++ b/suite/audio_quality/lib/src/task/TaskGeneric.cpp
@@ -124,7 +124,7 @@
 
 bool TaskGeneric::addStringAttribute(const android::String8& key, const android::String8& value)
 {
-    std::set<android::String8, android::String8>::iterator it = mAllowedStringAttributes.find(key);
+    auto it = mAllowedStringAttributes.find(key);
     if (it == mAllowedStringAttributes.end()) {
         return false; // not allowed
     }
@@ -134,7 +134,7 @@
 
 bool TaskGeneric::findStringAttribute(const android::String8& key, android::String8& value) const
 {
-    std::map<android::String8, android::String8>::const_iterator it = mStringAttributes.find(key);
+    auto it = mStringAttributes.find(key);
     if (it == mStringAttributes.end()) {
         return false; // not found
     }
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
index 36acd82..ecd9792 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
@@ -24,6 +24,7 @@
 
 import android.alarmmanager.alarmtestapp.cts.TestAlarmReceiver;
 import android.alarmmanager.alarmtestapp.cts.TestAlarmScheduler;
+import android.app.AlarmManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -36,6 +37,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
+import android.util.LongArray;
 
 import com.android.compatibility.common.util.AppStandbyUtils;
 
@@ -59,49 +61,93 @@
     private static final String TEST_APP_PACKAGE = "android.alarmmanager.alarmtestapp.cts";
     private static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestAlarmScheduler";
 
-    private static final long DEFAULT_WAIT = 4_000;
+    private static final long DEFAULT_WAIT = 2_000;
     private static final long POLL_INTERVAL = 200;
 
     // Tweaked alarm manager constants to facilitate testing
-    private static final long ALLOW_WHILE_IDLE_SHORT_TIME = 15_000;
-    private static final long MIN_FUTURITY = 2_000;
-    private static final long[] APP_STANDBY_DELAYS = {0, 10_000, 20_000, 30_000, 600_000};
+    private static final long ALLOW_WHILE_IDLE_SHORT_TIME = 10_000;
+    private static final long MIN_FUTURITY = 1_000;
+
+    // Not touching ACTIVE and RARE parameters for this test
+    private static final int WORKING_INDEX = 0;
+    private static final int FREQUENT_INDEX = 1;
+    private static final int RARE_INDEX = 2;
     private static final String[] APP_BUCKET_TAGS = {
-            "active",
             "working_set",
             "frequent",
             "rare",
-            "never"
     };
-    private static final String[] APP_BUCKET_KEYS = {
-            "standby_active_delay",
+    private static final String[] APP_BUCKET_DELAY_KEYS = {
             "standby_working_delay",
             "standby_frequent_delay",
             "standby_rare_delay",
-            "standby_never_delay",
     };
+    private static final long[] APP_STANDBY_DELAYS = {
+            5_000,   // Working set
+            10_000,   // Frequent
+            15_000,  // Rare
+    };
+    private static final long APP_STANDBY_WINDOW = 10_000;
+    private static final String[] APP_BUCKET_QUOTA_KEYS = {
+            "standby_working_quota",
+            "standby_frequent_quota",
+            "standby_rare_quota",
+    };
+    private static final int[] APP_STANDBY_QUOTAS = {
+            5,  // Working set
+            3,  // Frequent
+            1,  // Rare
+    };
+
+    // Settings common for all tests
+    private static final String COMMON_SETTINGS;
+
+    static {
+        final StringBuilder settings = new StringBuilder();
+        settings.append("min_futurity=");
+        settings.append(MIN_FUTURITY);
+        settings.append(",allow_while_idle_short_time=");
+        settings.append(ALLOW_WHILE_IDLE_SHORT_TIME);
+        for (int i = 0; i < APP_STANDBY_DELAYS.length; i++) {
+            settings.append(",");
+            settings.append(APP_BUCKET_DELAY_KEYS[i]);
+            settings.append("=");
+            settings.append(APP_STANDBY_DELAYS[i]);
+        }
+        settings.append(",app_standby_window=");
+        settings.append(APP_STANDBY_WINDOW);
+        for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) {
+            settings.append(",");
+            settings.append(APP_BUCKET_QUOTA_KEYS[i]);
+            settings.append("=");
+            settings.append(APP_STANDBY_QUOTAS[i]);
+        }
+        COMMON_SETTINGS = settings.toString();
+    }
 
     // Save the state before running tests to restore it after we finish testing.
     private static boolean sOrigAppStandbyEnabled;
+    // Test app's alarm history to help predict when a subsequent alarm is going to get deferred.
+    private static TestAlarmHistory sAlarmHistory;
 
     private Context mContext;
     private ComponentName mAlarmScheduler;
     private UiDevice mUiDevice;
     private AtomicInteger mAlarmCount;
-    private volatile long mLastAlarmTime;
 
     private final BroadcastReceiver mAlarmStateReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             mAlarmCount.getAndAdd(intent.getIntExtra(TestAlarmReceiver.EXTRA_ALARM_COUNT, 1));
-            mLastAlarmTime = SystemClock.elapsedRealtime();
-            Log.d(TAG, "No. of expirations: " + mAlarmCount
-                    + " elapsed: " + SystemClock.elapsedRealtime());
+            final long nowElapsed = SystemClock.elapsedRealtime();
+            sAlarmHistory.addTime(nowElapsed);
+            Log.d(TAG, "No. of expirations: " + mAlarmCount + " elapsed: " + nowElapsed);
         }
     };
 
     @BeforeClass
     public static void setUpTests() throws Exception {
+        sAlarmHistory = new TestAlarmHistory();
         sOrigAppStandbyEnabled = AppStandbyUtils.isAppStandbyEnabledAtRuntime();
         if (!sOrigAppStandbyEnabled) {
             AppStandbyUtils.setAppStandbyEnabledAtRuntime(true);
@@ -117,16 +163,12 @@
         mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
         mAlarmScheduler = new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER);
         mAlarmCount = new AtomicInteger(0);
-        updateAlarmManagerConstants();
+        updateAlarmManagerConstants(true);
         setBatteryCharging(false);
         final IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(TestAlarmReceiver.ACTION_REPORT_ALARM_EXPIRED);
         mContext.registerReceiver(mAlarmStateReceiver, intentFilter);
         assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
-        setAppStandbyBucket("active");
-        scheduleAlarm(SystemClock.elapsedRealtime(), false, 0);
-        Thread.sleep(MIN_FUTURITY);
-        assertTrue("Alarm not sent when app in active", waitForAlarms(1));
     }
 
     private void scheduleAlarm(long triggerMillis, boolean allowWhileIdle, long interval) {
@@ -140,50 +182,99 @@
         mContext.sendBroadcast(setAlarmIntent);
     }
 
+    private void scheduleAlarmClock(long triggerRTC) {
+        AlarmManager.AlarmClockInfo alarmInfo = new AlarmManager.AlarmClockInfo(triggerRTC, null);
+
+        final Intent setAlarmClockIntent = new Intent(TestAlarmScheduler.ACTION_SET_ALARM_CLOCK);
+        setAlarmClockIntent.setComponent(mAlarmScheduler);
+        setAlarmClockIntent.putExtra(TestAlarmScheduler.EXTRA_ALARM_CLOCK_INFO, alarmInfo);
+        mContext.sendBroadcast(setAlarmClockIntent);
+    }
+
+
     private void testBucketDelay(int bucketIndex) throws Exception {
-        setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
-        final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
-        final long minTriggerTime = mLastAlarmTime + APP_STANDBY_DELAYS[bucketIndex];
-        scheduleAlarm(triggerTime, false, 0);
+        setAppStandbyBucket("active");
+        final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        scheduleAlarm(firstTrigger, false, 0);
         Thread.sleep(MIN_FUTURITY);
-        if (triggerTime + DEFAULT_WAIT < minTriggerTime) {
+        assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+        setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
+        final long nextTriggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        final long minTriggerTime = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[bucketIndex];
+        scheduleAlarm(nextTriggerTime, false, 0);
+        Thread.sleep(MIN_FUTURITY);
+        if (nextTriggerTime + DEFAULT_WAIT < minTriggerTime) {
             assertFalse("Alarm went off before " + APP_BUCKET_TAGS[bucketIndex] + " delay",
-                    waitForAlarms(1));
-            Thread.sleep(minTriggerTime - SystemClock.elapsedRealtime());
+                    waitForAlarm());
         }
+        Thread.sleep(minTriggerTime - SystemClock.elapsedRealtime());
         assertTrue("Deferred alarm did not go off after " + APP_BUCKET_TAGS[bucketIndex] + " delay",
-                waitForAlarms(1));
+                waitForAlarm());
+    }
+
+    @Test
+    public void testActiveDelay() throws Exception {
+        updateAlarmManagerConstants(false);
+        setAppStandbyBucket("active");
+        long nextTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        for (int i = 0; i < 3; i++) {
+            scheduleAlarm(nextTrigger, false, 0);
+            Thread.sleep(MIN_FUTURITY);
+            assertTrue("Alarm not received as expected when app is in active", waitForAlarm());
+            nextTrigger += MIN_FUTURITY;
+        }
     }
 
     @Test
     public void testWorkingSetDelay() throws Exception {
-        testBucketDelay(1);
+        updateAlarmManagerConstants(false);
+        testBucketDelay(WORKING_INDEX);
     }
 
     @Test
     public void testFrequentDelay() throws Exception {
-        testBucketDelay(2);
+        updateAlarmManagerConstants(false);
+        testBucketDelay(FREQUENT_INDEX);
     }
 
     @Test
     public void testRareDelay() throws Exception {
-        testBucketDelay(3);
+        updateAlarmManagerConstants(false);
+        testBucketDelay(RARE_INDEX);
+    }
+
+    @Test
+    public void testNeverDelay() throws Exception {
+        updateAlarmManagerConstants(false);
+        setAppStandbyBucket("never");
+        final long expectedTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        scheduleAlarm(expectedTrigger, true, 0);
+        Thread.sleep(10_000);
+        assertFalse("Alarm received when app was in never bucket", waitForAlarm());
     }
 
     @Test
     public void testBucketUpgradeToSmallerDelay() throws Exception {
-        setAppStandbyBucket(APP_BUCKET_TAGS[2]);
+        updateAlarmManagerConstants(false);
+        setAppStandbyBucket("active");
+        final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        scheduleAlarm(firstTrigger, false, 0);
+        Thread.sleep(MIN_FUTURITY);
+        assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+        setAppStandbyBucket(APP_BUCKET_TAGS[FREQUENT_INDEX]);
         final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
-        final long workingSetExpectedTrigger = mLastAlarmTime + APP_STANDBY_DELAYS[1];
+        final long workingSetExpectedTrigger = sAlarmHistory.getLast(1)
+                + APP_STANDBY_DELAYS[WORKING_INDEX];
         scheduleAlarm(triggerTime, false, 0);
         Thread.sleep(workingSetExpectedTrigger - SystemClock.elapsedRealtime());
-        assertFalse("The alarm went off before frequent delay", waitForAlarms(1));
-        setAppStandbyBucket(APP_BUCKET_TAGS[1]);
+        assertFalse("The alarm went off before frequent delay", waitForAlarm());
+        setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
         assertTrue("The alarm did not go off when app bucket upgraded to working_set",
-                waitForAlarms(1));
+                waitForAlarm());
     }
 
-
     /**
      * This is different to {@link #testBucketUpgradeToSmallerDelay()} in the sense that the bucket
      * upgrade shifts eligibility to a point earlier than when the alarm is scheduled for.
@@ -192,61 +283,148 @@
      */
     @Test
     public void testBucketUpgradeToNoDelay() throws Exception {
-        setAppStandbyBucket(APP_BUCKET_TAGS[3]);
-        final long triggerTime1 = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+        updateAlarmManagerConstants(false);
+
+        setAppStandbyBucket("active");
+        final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        scheduleAlarm(firstTrigger, false, 0);
+        Thread.sleep(MIN_FUTURITY);
+        assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+        setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
+        final long triggerTime1 = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[FREQUENT_INDEX];
         scheduleAlarm(triggerTime1, false, 0);
         Thread.sleep(triggerTime1 - SystemClock.elapsedRealtime());
         assertFalse("The alarm went off after frequent delay when app in rare bucket",
-                waitForAlarms(1));
-        setAppStandbyBucket(APP_BUCKET_TAGS[1]);
+                waitForAlarm());
+        setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
         assertTrue("The alarm did not go off when app bucket upgraded to working_set",
-                waitForAlarms(1));
+                waitForAlarm());
 
         // Once more
-        setAppStandbyBucket(APP_BUCKET_TAGS[3]);
-        final long triggerTime2 = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+        setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
+        final long triggerTime2 = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[FREQUENT_INDEX];
         scheduleAlarm(triggerTime2, false, 0);
-        setAppStandbyBucket(APP_BUCKET_TAGS[0]);
+        setAppStandbyBucket("active");
         Thread.sleep(triggerTime2 - SystemClock.elapsedRealtime());
         assertTrue("The alarm did not go off as scheduled when the app was in active",
-                waitForAlarms(1));
+                waitForAlarm());
+    }
+
+    public void testSimpleQuotaDeferral(int bucketIndex) throws Exception {
+        setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
+        final int quota = APP_STANDBY_QUOTAS[bucketIndex];
+
+        long startElapsed = SystemClock.elapsedRealtime();
+        final long freshWindowPoint = sAlarmHistory.getLast(1) + APP_STANDBY_WINDOW + 1;
+        if (freshWindowPoint > startElapsed) {
+            Thread.sleep(freshWindowPoint - startElapsed);
+            startElapsed = freshWindowPoint;
+            // Now we should have no alarms in the past APP_STANDBY_WINDOW
+        }
+        final long desiredTrigger = startElapsed + APP_STANDBY_WINDOW;
+        final long firstTrigger = startElapsed + 4_000;
+        assertTrue("Quota too large for test",
+                firstTrigger + ((quota - 1) * MIN_FUTURITY) < desiredTrigger);
+        for (int i = 0; i < quota; i++) {
+            final long trigger = firstTrigger + (i * MIN_FUTURITY);
+            scheduleAlarm(trigger, false, 0);
+            Thread.sleep(trigger - SystemClock.elapsedRealtime());
+            assertTrue("Alarm within quota not firing as expected", waitForAlarm());
+        }
+
+        // Now quota is reached, any subsequent alarm should get deferred.
+        scheduleAlarm(desiredTrigger, false, 0);
+        Thread.sleep(desiredTrigger - SystemClock.elapsedRealtime());
+        assertFalse("Alarm exceeding quota not deferred", waitForAlarm());
+        final long minTrigger = firstTrigger + 1 + APP_STANDBY_WINDOW;
+        Thread.sleep(minTrigger - SystemClock.elapsedRealtime());
+        assertTrue("Alarm exceeding quota not delivered after expected delay", waitForAlarm());
+    }
+
+    @Test
+    public void testActiveQuota() throws Exception {
+        setAppStandbyBucket("active");
+        long nextTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        for (int i = 0; i < 3; i++) {
+            scheduleAlarm(nextTrigger, false, 0);
+            Thread.sleep(MIN_FUTURITY);
+            assertTrue("Alarm not received as expected when app is in active", waitForAlarm());
+            nextTrigger += MIN_FUTURITY;
+        }
+    }
+
+    @Test
+    public void testWorkingQuota() throws Exception {
+        testSimpleQuotaDeferral(WORKING_INDEX);
+    }
+
+    @Test
+    public void testFrequentQuota() throws Exception {
+        testSimpleQuotaDeferral(FREQUENT_INDEX);
+    }
+
+    @Test
+    public void testRareQuota() throws Exception {
+        testSimpleQuotaDeferral(RARE_INDEX);
+    }
+
+    @Test
+    public void testNeverQuota() throws Exception {
+        setAppStandbyBucket("never");
+        final long expectedTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+        scheduleAlarm(expectedTrigger, true, 0);
+        Thread.sleep(10_000);
+        assertFalse("Alarm received when app was in never bucket", waitForAlarm());
+    }
+
+    @Test
+    public void testAlarmClockUnaffected() throws Exception {
+        setAppStandbyBucket("never");
+        final long trigger = System.currentTimeMillis() + MIN_FUTURITY;
+        scheduleAlarmClock(trigger);
+        Thread.sleep(MIN_FUTURITY);
+        assertTrue("Alarm clock not received as expected", waitForAlarm());
     }
 
     @Test
     public void testAllowWhileIdleAlarms() throws Exception {
+        updateAlarmManagerConstants(false);
+        setAppStandbyBucket("active");
         final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
         scheduleAlarm(firstTrigger, true, 0);
         Thread.sleep(MIN_FUTURITY);
-        assertTrue("first allow_while_idle alarm did not go off as scheduled", waitForAlarms(1));
-        scheduleAlarm(mLastAlarmTime + 9_000, true, 0);
+        assertTrue("first allow_while_idle alarm did not go off as scheduled", waitForAlarm());
+        scheduleAlarm(sAlarmHistory.getLast(1) + 7_000, true, 0);
         // First check for the case where allow_while_idle delay should supersede app standby
-        setAppStandbyBucket(APP_BUCKET_TAGS[1]);
-        Thread.sleep(APP_STANDBY_DELAYS[1]);
-        assertFalse("allow_while_idle alarm went off before short time", waitForAlarms(1));
-        long expectedTriggerTime = mLastAlarmTime + ALLOW_WHILE_IDLE_SHORT_TIME;
+        setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
+        Thread.sleep(APP_STANDBY_DELAYS[WORKING_INDEX]);
+        assertFalse("allow_while_idle alarm went off before short time", waitForAlarm());
+        long expectedTriggerTime = sAlarmHistory.getLast(1) + ALLOW_WHILE_IDLE_SHORT_TIME;
         Thread.sleep(expectedTriggerTime - SystemClock.elapsedRealtime());
-        assertTrue("allow_while_idle alarm did not go off after short time", waitForAlarms(1));
+        assertTrue("allow_while_idle alarm did not go off after short time", waitForAlarm());
 
         // Now the other case, app standby delay supersedes the allow_while_idle delay
-        scheduleAlarm(mLastAlarmTime + 12_000, true, 0);
-        setAppStandbyBucket(APP_BUCKET_TAGS[2]);
+        scheduleAlarm(sAlarmHistory.getLast(1) + 7_000, true, 0);
+        setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
         Thread.sleep(ALLOW_WHILE_IDLE_SHORT_TIME);
-        assertFalse("allow_while_idle alarm went off before " + APP_STANDBY_DELAYS[2]
-                + "ms, when in bucket " + APP_BUCKET_TAGS[2], waitForAlarms(1));
-        expectedTriggerTime = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+        assertFalse("allow_while_idle alarm went off before " + APP_STANDBY_DELAYS[RARE_INDEX]
+                + "ms, when in bucket " + APP_BUCKET_TAGS[RARE_INDEX], waitForAlarm());
+        expectedTriggerTime = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[RARE_INDEX];
         Thread.sleep(expectedTriggerTime - SystemClock.elapsedRealtime());
-        assertTrue("allow_while_idle alarm did not go off even after " + APP_STANDBY_DELAYS[2]
-                + "ms, when in bucket " + APP_BUCKET_TAGS[2], waitForAlarms(1));
+        assertTrue("allow_while_idle alarm did not go off even after "
+                + APP_STANDBY_DELAYS[RARE_INDEX]
+                + "ms, when in bucket " + APP_BUCKET_TAGS[RARE_INDEX], waitForAlarm());
     }
 
     @Test
     public void testPowerWhitelistedAlarmNotBlocked() throws Exception {
-        setAppStandbyBucket(APP_BUCKET_TAGS[3]);
+        setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
         setPowerWhitelisted(true);
         final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
         scheduleAlarm(triggerTime, false, 0);
         Thread.sleep(MIN_FUTURITY);
-        assertTrue("Alarm did not go off for whitelisted app in rare bucket", waitForAlarms(1));
+        assertTrue("Alarm did not go off for whitelisted app in rare bucket", waitForAlarm());
         setPowerWhitelisted(false);
     }
 
@@ -270,13 +448,11 @@
         }
     }
 
-    private void updateAlarmManagerConstants() throws IOException {
+    private void updateAlarmManagerConstants(boolean enableQuota) throws IOException {
         final StringBuffer cmd = new StringBuffer("settings put global alarm_manager_constants ");
-        cmd.append("min_futurity="); cmd.append(MIN_FUTURITY);
-        cmd.append(",allow_while_idle_short_time="); cmd.append(ALLOW_WHILE_IDLE_SHORT_TIME);
-        for (int i = 0; i < APP_STANDBY_DELAYS.length; i++) {
-            cmd.append(",");
-            cmd.append(APP_BUCKET_KEYS[i]); cmd.append("="); cmd.append(APP_STANDBY_DELAYS[i]);
+        cmd.append(COMMON_SETTINGS);
+        if (!enableQuota) {
+            cmd.append(",app_standby_quotas_enabled=false");
         }
         executeAndLog(cmd.toString());
     }
@@ -311,8 +487,8 @@
         return output;
     }
 
-    private boolean waitForAlarms(final int numAlarms) throws InterruptedException {
-        final boolean success = waitUntil(() -> (mAlarmCount.get() == numAlarms), DEFAULT_WAIT);
+    private boolean waitForAlarm() throws InterruptedException {
+        final boolean success = waitUntil(() -> (mAlarmCount.get() == 1), DEFAULT_WAIT);
         mAlarmCount.set(0);
         return success;
     }
@@ -325,6 +501,24 @@
         return condition.isMet();
     }
 
+    private static final class TestAlarmHistory {
+        private LongArray mHistory = new LongArray();
+
+        private synchronized void addTime(long timestamp) {
+            mHistory.add(timestamp);
+        }
+
+        /**
+         * Get the xth alarm time from the end.
+         */
+        private synchronized long getLast(int x) {
+            if (x == 0 || x > mHistory.size()) {
+                return 0;
+            }
+            return mHistory.get(mHistory.size() - x);
+        }
+    }
+
     @FunctionalInterface
     interface Condition {
         boolean isMet();
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
index a981e5a..f36b07f 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
@@ -136,7 +136,7 @@
     @Test
     public void testAlarmClockNotBlocked() throws Exception {
         final long nowRTC = System.currentTimeMillis();
-        final long waitInterval = 10_000;
+        final long waitInterval = 3_000;
         final long triggerRTC = nowRTC + waitInterval;
         scheduleAlarmClock(triggerRTC);
         Thread.sleep(waitInterval);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
index 3fbccc7..5e7745a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
@@ -119,6 +119,7 @@
 
     public static void homeScreenOrBust(Context context, UiAutomation uiAutomation) {
         wakeUpOrBust(context, uiAutomation);
+        if (context.getPackageManager().isInstantApp()) return;
         if (isHomeScreenShowing(context, uiAutomation)) return;
         try {
             executeAndWaitOn(
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index ad1fd91..8bd83e2 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -46,6 +46,7 @@
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -66,6 +67,7 @@
     private boolean mManagedProfiles;
     private PackageManager mPackageManager;
     private NotificationManager mNotificationManager;
+    private boolean mHasSecureLockScreen;
 
     private static final String TEST_CA_STRING1 =
             "-----BEGIN CERTIFICATE-----\n" +
@@ -98,6 +100,8 @@
         mDeviceAdmin = mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
         mManagedProfiles = mDeviceAdmin
                 && mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+        mHasSecureLockScreen =
+                mPackageManager.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
     }
 
     public void testGetActiveAdmins() {
@@ -870,7 +874,7 @@
     }
 
     public void testSetResetPasswordToken_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
+        if (!mDeviceAdmin || !mHasSecureLockScreen) {
             Log.w(TAG, "Skipping testSetResetPasswordToken_failIfNotDeviceOwner");
             return;
         }
@@ -883,7 +887,7 @@
     }
 
     public void testClearResetPasswordToken_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
+        if (!mDeviceAdmin || !mHasSecureLockScreen) {
             Log.w(TAG, "Skipping testClearResetPasswordToken_failIfNotDeviceOwner");
             return;
         }
@@ -896,7 +900,7 @@
     }
 
     public void testIsResetPasswordTokenActive_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
+        if (!mDeviceAdmin || !mHasSecureLockScreen) {
             Log.w(TAG, "Skipping testIsResetPasswordTokenActive_failIfNotDeviceOwner");
             return;
         }
@@ -909,7 +913,7 @@
     }
 
     public void testResetPasswordWithToken_failIfNotDeviceOrProfileOwner() {
-        if (!mDeviceAdmin) {
+        if (!mDeviceAdmin || !mHasSecureLockScreen) {
             Log.w(TAG, "Skipping testResetPasswordWithToken_failIfNotDeviceOwner");
             return;
         }
@@ -922,7 +926,7 @@
     }
 
     public void testIsUsingUnifiedPassword_failIfNotProfileOwner() {
-        if (!mDeviceAdmin) {
+        if (!mDeviceAdmin || !mHasSecureLockScreen) {
             Log.w(TAG, "Skipping testIsUsingUnifiedPassword_failIfNotProfileOwner");
             return;
         }
@@ -1058,14 +1062,9 @@
             return;
         }
         try {
-            mDevicePolicyManager.addCrossProfileCalendarPackage(mComponent, TEST_PACKAGE_NAME);
-            fail("addCrossProfileCalendarPackage did not throw expected SecurityException");
-        } catch (SecurityException e) {
-            assertProfileOwnerMessage(e.getMessage());
-        }
-        try {
-            mDevicePolicyManager.removeCrossProfileCalendarPackage(mComponent, TEST_PACKAGE_NAME);
-            fail("removeCrossProfileCalendarPackage did not throw expected SecurityException");
+            mDevicePolicyManager.setCrossProfileCalendarPackages(mComponent,
+                    Collections.singleton(TEST_PACKAGE_NAME));
+            fail("setCrossProfileCalendarPackages did not throw expected SecurityException");
         } catch (SecurityException e) {
             assertProfileOwnerMessage(e.getMessage());
         }
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index fb20e53..fef8625 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -152,7 +152,7 @@
             </intent-filter>
         </service>
 
-        <service android:name="android.app.stubs.IsolatedService" android:isolatedProcess="true">
+        <service android:name="android.app.stubs.IsolatedService" android:isolatedProcess="true" android:useAppZygote="true">
         </service>
 
         <activity android:name="android.app.stubs.TestedScreen"
diff --git a/tests/app/app/res/xml/wallpaper.xml b/tests/app/app/res/xml/wallpaper.xml
index bce8793..e86c9b9 100644
--- a/tests/app/app/res/xml/wallpaper.xml
+++ b/tests/app/app/res/xml/wallpaper.xml
@@ -20,6 +20,7 @@
     android:author="@string/wallpaper_collection"
     android:description="@string/wallpaper_description"
     android:showMetadataInPreview="true"
+    android:supportsMultipleDisplays="true"
     android:contextDescription="@string/wallpaper_context"
     android:contextUri="@string/wallpaper_context_uri"
     android:settingsSliceUri="@string/wallpaper_slice_uri"
diff --git a/tests/app/app/src/android/app/stubs/LocalService.java b/tests/app/app/src/android/app/stubs/LocalService.java
index 6120a77..f914cdf 100644
--- a/tests/app/app/src/android/app/stubs/LocalService.java
+++ b/tests/app/app/src/android/app/stubs/LocalService.java
@@ -46,6 +46,8 @@
     public static final int SET_VALUE_CODE = 7;
     public static final int GET_PID_CODE = 8;
     public static final int GET_UID_CODE = 9;
+    public static final int GET_PPID_CODE = 10;
+    public static final int GET_ZYGOTE_PRELOAD_CALLED = 11;
 
     public static Context sServiceContext = null;
 
@@ -78,6 +80,14 @@
                     data.enforceInterface(SERVICE_LOCAL);
                     reply.writeInt(Process.myUid());
                     return true;
+                case GET_PPID_CODE:
+                    data.enforceInterface(SERVICE_LOCAL);
+                    reply.writeInt(Process.myPpid());
+                    return true;
+                case GET_ZYGOTE_PRELOAD_CALLED:
+                    data.enforceInterface(SERVICE_LOCAL);
+                    reply.writeBoolean(ZygotePreload.preloadCalled());
+                    return true;
                 default:
                     return super.onTransact(code, data, reply, flags);
             }
diff --git a/tests/app/app/src/android/app/stubs/ZygotePreload.java b/tests/app/app/src/android/app/stubs/ZygotePreload.java
new file mode 100644
index 0000000..1faef7c
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ZygotePreload.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.stubs;
+
+import android.os.Process;
+import android.util.Log;
+
+public class ZygotePreload {
+    static final String TAG = "ZygotePreload";
+
+    static boolean sPreloadCalled = false;
+
+    static synchronized public boolean preloadCalled() {
+        return sPreloadCalled;
+    }
+
+    static synchronized public void doPreload() {
+        sPreloadCalled = true;
+    }
+}
diff --git a/tests/app/src/android/app/cts/DisplayTest.java b/tests/app/src/android/app/cts/DisplayTest.java
index f845bb7..4bb6c40 100644
--- a/tests/app/src/android/app/cts/DisplayTest.java
+++ b/tests/app/src/android/app/cts/DisplayTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Point;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.Display;
+import static com.android.compatibility.common.util.PackageUtil.supportsRotation;
 
 /**
  * Tests to verify functionality of {@link Display}.
@@ -48,6 +49,11 @@
      * updated adjustments after a rotation.
      */
     public void testRotation() throws Throwable {
+        if (!supportsRotation()) {
+            // Skip rotation test if device doesn't support it.
+            return;
+        }
+
         // Get a {@link Display} instance before rotation.
         final Display origDisplay = mActivity.getDisplay();
 
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index fa5e8064..76cd58c 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -45,6 +45,7 @@
 import android.provider.MediaStore;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.webkit.cts.CtsTestServer;
@@ -485,7 +486,7 @@
      * updates to this entry in DownlaodProvider are reflected in MediaProvider as well.
      */
     @Test
-    public void testDownloadManager_mediaStoreUpdates() throws Exception {
+    public void testDownloadManagerUpdates() throws Exception {
         final File dataDir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
         dataDir.mkdir();
         final File downloadFile = new File(dataDir, "colors.txt");
@@ -531,6 +532,48 @@
         }
     }
 
+    @Test
+    public void testDownloadManager_mediaStoreUpdates() throws Exception {
+        final File dataDir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
+        dataDir.mkdir();
+        final File downloadFile = new File(dataDir, "colors.txt");
+        downloadFile.createNewFile();
+        final String fileContents = "RED;GREEN;BLUE";
+        try (final PrintWriter pw = new PrintWriter(downloadFile)) {
+            pw.print(fileContents);
+        }
+
+        // Insert into DownloadProvider and verify it's added to MediaProvider as well
+        final String testTitle = "Test_title";
+        final long downloadId = mDownloadManager.addCompletedDownload(testTitle, "Test desc", true,
+                "text/plain", downloadFile.getPath(), fileContents.getBytes().length, true);
+        assertTrue(downloadId >= 0);
+        final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
+        try (Cursor cursor = mContext.getContentResolver().query(downloadUri,
+                new String[] { DownloadManager.COLUMN_TITLE }, null, null)) {
+            cursor.moveToNext();
+            assertEquals(testTitle, cursor.getString(0));
+        }
+
+        final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
+        final String newTitle = "New_title";
+        updateUri(mediaStoreUri, "_display_name", newTitle);
+        try (Cursor cursor = mContext.getContentResolver().query(downloadUri,
+                new String[] { DownloadManager.COLUMN_TITLE }, null, null)) {
+            cursor.moveToNext();
+            assertEquals(newTitle, cursor.getString(0));
+        }
+
+        assertRemoveDownload(downloadId, 0);
+    }
+
+    private void updateUri(Uri uri, String column, String value) throws Exception {
+        final String cmd = String.format("content update --uri %s --bind %s:s:%s",
+                uri, column, value);
+        final String res = runShellCommand(cmd).trim();
+        assertTrue(res, TextUtils.isEmpty(res));
+    }
+
     private static byte[] hash(InputStream in) throws Exception {
         try (DigestInputStream digestIn = new DigestInputStream(in,
                 MessageDigest.getInstance("SHA-1"));
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index b369703..f8fe35c1 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -21,7 +21,6 @@
 
 import android.app.Notification;
 import android.app.NotificationChannel;
-import android.app.NotificationManager;
 import android.graphics.Color;
 import android.media.AudioAttributes;
 import android.net.Uri;
@@ -59,7 +58,7 @@
         assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, channel.getAudioAttributes());
         assertEquals(null, channel.getGroup());
         assertTrue(channel.getLightColor() == 0);
-        assertTrue(channel.canOverlayApps());
+        assertTrue(channel.canBubble());
     }
 
     public void testWriteToParcel() {
@@ -155,18 +154,18 @@
         assertEquals("banana", channel.getGroup());
     }
 
-    public void testAppOverlay() {
+    public void testBubble() {
         NotificationChannel channel =
                 new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
-        channel.setAllowAppOverlay(true);
-        assertEquals("Only HIGH channels can have app overlays", false, channel.canOverlayApps());
+        channel.setAllowBubbles(true);
+        assertEquals("Only HIGH channels can have bubbles", false, channel.canBubble());
 
         channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
-        channel.setAllowAppOverlay(false);
-        assertEquals(false, channel.canOverlayApps());
+        channel.setAllowBubbles(false);
+        assertEquals(false, channel.canBubble());
 
         channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
-        channel.setAllowAppOverlay(true);
-        assertEquals(true, channel.canOverlayApps());
+        channel.setAllowBubbles(true);
+        assertEquals(true, channel.canBubble());
     }
 }
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index ec1d91f..d99cb11 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1510,8 +1510,8 @@
         }
     }
 
-    public void testAreAppOverlaysAllowed() {
-        assertTrue(mNotificationManager.areAppOverlaysAllowed());
+    public void testAreBubblesAllowed() {
+        assertTrue(mNotificationManager.areBubblesAllowed());
     }
 
     public void testNotificationIcon() {
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
index 1f25528..18a8776 100644
--- a/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -25,7 +25,6 @@
 import android.app.PendingIntent;
 import android.app.Person;
 import android.app.RemoteInput;
-import android.app.stubs.R;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Icon;
@@ -56,6 +55,8 @@
     private static final String CONTENT_TEXT = "contentText";
     private static final String URI_STRING = "uriString";
     private static final String ACTION_TITLE = "actionTitle";
+    private static final String BUBBLE_TITLE = "bubbleTitle";
+    private static final int BUBBLE_HEIGHT = 300;
     private static final int TOLERANCE = 200;
     private static final long TIMEOUT = 4000;
     private static final NotificationChannel CHANNEL = new NotificationChannel("id", "name",
@@ -121,14 +122,14 @@
     }
 
     public void testWriteToParcel() {
-        PendingIntent overlayIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Notification.BubbleMetadata bubble = makeBubbleMetadata();
         mNotification = new Notification.Builder(mContext, CHANNEL.getId())
                 .setBadgeIconType(Notification.BADGE_ICON_SMALL)
                 .setShortcutId(SHORTCUT_ID)
                 .setTimeoutAfter(TIMEOUT)
                 .setSettingsText(SETTING_TEXT)
                 .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
-                .setAppOverlayIntent(overlayIntent)
+                .setBubbleMetadata(bubble)
                 .setAllowSystemGeneratedContextualActions(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS)
                 .build();
         mNotification.icon = 0;
@@ -186,7 +187,7 @@
         assertEquals(mNotification.getChannelId(), result.getChannelId());
         assertEquals(mNotification.getSettingsText(), result.getSettingsText());
         assertEquals(mNotification.getGroupAlertBehavior(), result.getGroupAlertBehavior());
-        assertEquals(overlayIntent, result.getAppOverlayIntent());
+        assertNotNull(result.getBubbleMetadata());
         assertEquals(mNotification.getAllowSystemGeneratedContextualActions(),
                 result.getAllowSystemGeneratedContextualActions());
 
@@ -239,7 +240,7 @@
     public void testBuilder() {
         final Intent intent = new Intent();
         final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        PendingIntent overlayIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+        Notification.BubbleMetadata bubble = makeBubbleMetadata();
         mNotification = new Notification.Builder(mContext, CHANNEL.getId())
                 .setSmallIcon(1)
                 .setContentTitle(CONTENT_TITLE)
@@ -250,7 +251,7 @@
                 .setTimeoutAfter(TIMEOUT)
                 .setSettingsText(SETTING_TEXT)
                 .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
-                .setAppOverlayIntent(overlayIntent)
+                .setBubbleMetadata(bubble)
                 .setAllowSystemGeneratedContextualActions(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS)
                 .build();
         assertEquals(CONTENT_TEXT, mNotification.extras.getString(Notification.EXTRA_TEXT));
@@ -263,7 +264,7 @@
         assertEquals(TIMEOUT, mNotification.getTimeoutAfter());
         assertEquals(SETTING_TEXT, mNotification.getSettingsText());
         assertEquals(Notification.GROUP_ALERT_SUMMARY, mNotification.getGroupAlertBehavior());
-        assertEquals(overlayIntent, mNotification.getAppOverlayIntent());
+        assertEquals(bubble, mNotification.getBubbleMetadata());
         assertEquals(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS,
                 mNotification.getAllowSystemGeneratedContextualActions());
     }
@@ -572,6 +573,94 @@
         assertFalse(notification.getAllowSystemGeneratedContextualActions());
     }
 
+    public void testBubbleMetadataBuilder() {
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Icon icon = Icon.createWithResource(mContext, 1);
+        Notification.BubbleMetadata.Builder metadataBuilder =
+                new Notification.BubbleMetadata.Builder()
+                .setDesiredHeight(BUBBLE_HEIGHT)
+                .setTitle(BUBBLE_TITLE)
+                .setIcon(icon)
+                .setIntent(bubbleIntent);
+
+        Notification.BubbleMetadata data = metadataBuilder.build();
+        assertEquals(BUBBLE_HEIGHT, data.getDesiredHeight());
+        assertEquals(BUBBLE_TITLE, data.getTitle());
+        assertEquals(icon, data.getIcon());
+        assertEquals(bubbleIntent, data.getIntent());
+        assertFalse(data.getSuppressInitialNotification());
+        assertFalse(data.getAutoExpandBubble());
+    }
+
+    public void testBubbleMetadata_parcel() {
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Icon icon = Icon.createWithResource(mContext, 1);
+        Notification.BubbleMetadata metadata =
+                new Notification.BubbleMetadata.Builder()
+                        .setDesiredHeight(BUBBLE_HEIGHT)
+                        .setTitle(BUBBLE_TITLE)
+                        .setAutoExpandBubble(true)
+                        .setSuppressInitialNotification(true)
+                        .setIcon(icon)
+                        .setIntent(bubbleIntent)
+                        .build();
+
+        writeAndReadParcelable(metadata);
+        assertEquals(BUBBLE_TITLE, metadata.getTitle());
+        assertEquals(BUBBLE_HEIGHT, metadata.getDesiredHeight());
+        assertEquals(icon, metadata.getIcon());
+        assertEquals(bubbleIntent, metadata.getIntent());
+        assertTrue(metadata.getAutoExpandBubble());
+        assertTrue(metadata.getSuppressInitialNotification());
+
+    }
+
+    public void testBubbleMetadataBuilder_throwForNoIntent() {
+        Icon icon = Icon.createWithResource(mContext, 1);
+        Notification.BubbleMetadata.Builder metadataBuilder =
+                new Notification.BubbleMetadata.Builder()
+                .setDesiredHeight(BUBBLE_HEIGHT)
+                .setTitle(BUBBLE_TITLE)
+                .setIcon(icon);
+        try {
+            metadataBuilder.build();
+            fail("Should have thrown IllegalStateException, no pending intent");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
+    public void testBubbleMetadataBuilder_throwForNoTitle() {
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Icon icon = Icon.createWithResource(mContext, 1);
+        Notification.BubbleMetadata.Builder metadataBuilder =
+                new Notification.BubbleMetadata.Builder()
+                .setDesiredHeight(BUBBLE_HEIGHT)
+                .setIcon(icon)
+                .setIntent(bubbleIntent);
+        try {
+            metadataBuilder.build();
+            fail("Should have thrown IllegalStateException, no title");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
+    public void testBubbleMetadataBuilder_throwForNoIcon() {
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Notification.BubbleMetadata.Builder metadataBuilder =
+                new Notification.BubbleMetadata.Builder()
+                .setDesiredHeight(BUBBLE_HEIGHT)
+                .setTitle(BUBBLE_TITLE)
+                .setIntent(bubbleIntent);
+        try {
+            metadataBuilder.build();
+            fail("Should have thrown IllegalStateException, no icon");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+    }
+
     private static RemoteInput newDataOnlyRemoteInput() {
         return new RemoteInput.Builder(DATA_RESULT_KEY)
             .setAllowFreeFormInput(false)
@@ -623,4 +712,14 @@
         }
         return actionBuilder.build();
     }
+
+    private Notification.BubbleMetadata makeBubbleMetadata() {
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        return new Notification.BubbleMetadata.Builder()
+                        .setIntent(bubbleIntent)
+                        .setTitle(BUBBLE_TITLE)
+                        .setIcon(Icon.createWithResource(mContext, 1))
+                        .setDesiredHeight(BUBBLE_HEIGHT)
+                        .build();
+    }
 }
diff --git a/tests/app/src/android/app/cts/ServiceTest.java b/tests/app/src/android/app/cts/ServiceTest.java
index 3f32a86..720ec4a 100644
--- a/tests/app/src/android/app/cts/ServiceTest.java
+++ b/tests/app/src/android/app/cts/ServiceTest.java
@@ -79,6 +79,7 @@
     private static final String EXTERNAL_SERVICE_PACKAGE = "com.android.app2";
     private static final String EXTERNAL_SERVICE_COMPONENT =
             EXTERNAL_SERVICE_PACKAGE + "/android.app.stubs.LocalService";
+    private static final String APP_ZYGOTE_PROCESS_NAME = "android.app.stubs_zygote";
     private int mExpectedServiceState;
     private Context mContext;
     private Intent mLocalService;
@@ -209,6 +210,7 @@
         private IBinder mService;
         private int mUid;
         private int mPid;
+        private int mPpid;
 
         public IsolatedConnection() {
             mUid = mPid = -1;
@@ -247,6 +249,25 @@
             return mPid;
         }
 
+        public int getPpid() {
+            return mPpid;
+        }
+
+        public boolean zygotePreloadCalled() {
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+            try {
+                mService.transact(LocalService.GET_ZYGOTE_PRELOAD_CALLED, data, reply, 0);
+            } catch (RemoteException e) {
+                finishBad("DeadObjectException when sending reporting object");
+            }
+            boolean value = reply.readBoolean();
+            reply.recycle();
+            data.recycle();
+            return value;
+        }
+
         public void setValue(int value) {
             Parcel data = Parcel.obtain();
             data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
@@ -289,6 +310,21 @@
             return value;
         }
 
+        public int getPpidIpc() {
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+            try {
+                mService.transact(LocalService.GET_PPID_CODE, data, reply, 0);
+            } catch (RemoteException e) {
+                finishBad("DeadObjectException when sending reporting object");
+            }
+            int value = reply.readInt();
+            reply.recycle();
+            data.recycle();
+            return value;
+        }
+
         public int getUidIpc() {
             Parcel data = Parcel.obtain();
             Parcel reply = Parcel.obtain();
@@ -310,6 +346,7 @@
                 mService = service;
                 mUid = getUidIpc();
                 mPid = getPidIpc();
+                mPpid = getPpidIpc();
                 notifyAll();
             }
         }
@@ -1344,6 +1381,92 @@
         }
     }
 
+    @MediumTest
+    public void testAppZygotePreload() throws Exception {
+        IsolatedConnection conn = new IsolatedConnection();
+        try {
+            mContext.bindIsolatedService(
+                    mIsolatedService, conn, Context.BIND_AUTO_CREATE, "1");
+
+            conn.waitForService(DELAY);
+
+            // Verify application preload was done
+            assertTrue(conn.zygotePreloadCalled());
+        } finally {
+            if (conn != null) {
+                mContext.unbindService(conn);
+            }
+        }
+    }
+
+    @MediumTest
+    public void testAppZygoteServices() throws Exception {
+        IsolatedConnection conn1a = null;
+        IsolatedConnection conn1b = null;
+        IsolatedConnection conn2 = null;
+        int appZygotePid;
+        try {
+            conn1a = new IsolatedConnection();
+            mContext.bindIsolatedService(
+                    mIsolatedService, conn1a, Context.BIND_AUTO_CREATE, "1");
+            conn1b = new IsolatedConnection();
+            mContext.bindIsolatedService(
+                    mIsolatedService, conn1b, Context.BIND_AUTO_CREATE, "1");
+            conn2 = new IsolatedConnection();
+            mContext.bindIsolatedService(
+                    mIsolatedService, conn2, Context.BIND_AUTO_CREATE, "2");
+
+            conn1a.waitForService(DELAY);
+            conn1b.waitForService(DELAY);
+            conn2.waitForService(DELAY);
+
+            // Get PPID of each service, and verify they're identical
+            int ppid1a = conn1a.getPpid();
+            int ppid1b = conn1b.getPpid();
+            int ppid2 = conn2.getPpid();
+
+            assertEquals(ppid1a, ppid1b);
+            assertEquals(ppid1b, ppid2);
+            // Find the app zygote process hosting these
+            String result = SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
+                "ps -p " + Integer.toString(ppid1a) + " -o NAME=");
+            result = result.replaceAll("\\s+", "");
+            assertEquals(result, APP_ZYGOTE_PROCESS_NAME);
+            appZygotePid = ppid1a;
+        } finally {
+            if (conn2 != null) {
+                mContext.unbindService(conn2);
+            }
+            if (conn1b != null) {
+                mContext.unbindService(conn1b);
+            }
+            if (conn1a != null) {
+                mContext.unbindService(conn1a);
+            }
+        }
+        // Sleep for 2 seconds and bind a service again, see it uses the same Zygote
+        try {
+            conn1a = new IsolatedConnection();
+            mContext.bindIsolatedService(
+                    mIsolatedService, conn1a, Context.BIND_AUTO_CREATE, "1");
+
+            conn1a.waitForService(DELAY);
+
+            int ppid1a = conn1a.getPpid();
+            assertEquals(appZygotePid, ppid1a);
+        } finally {
+            if (conn1a != null) {
+                mContext.unbindService(conn1a);
+            }
+        }
+        // Sleep for 10 seconds, verify the app_zygote is gone
+        Thread.sleep(10000);
+        String result = SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
+            "ps -p " + Integer.toString(appZygotePid) + " -o NAME=");
+        result = result.replaceAll("\\s+", "");
+        assertEquals("", result);
+    }
+
     /**
      * Test that the system properly orders processes bound by an activity within the
      * LRU list.
diff --git a/tests/app/src/android/app/cts/WallpaperInfoTest.java b/tests/app/src/android/app/cts/WallpaperInfoTest.java
index 7cff609..123a9cd 100644
--- a/tests/app/src/android/app/cts/WallpaperInfoTest.java
+++ b/tests/app/src/android/app/cts/WallpaperInfoTest.java
@@ -59,6 +59,7 @@
         assertEquals(context.getString(R.string.wallpaper_slice_uri),
             wallpaperInfo.getSettingsSliceUri().toString());
         assertEquals(true, wallpaperInfo.getShowMetadataInPreview());
+        assertEquals(true, wallpaperInfo.supportsMultipleDisplays());
         assertNotNull(wallpaperInfo.loadIcon(pm));
         assertNotNull(wallpaperInfo.loadThumbnail(pm));
     }
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index f27e663..5955274 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -156,6 +156,16 @@
                 <action android:name="android.service.autofill.AutofillService" />
             </intent-filter>
         </service>
+
+        <service
+            android:name=".augmented.CtsAugmentedAutofillService"
+            android:label="CtsAugmentedAutofillService"
+            android:permission="android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.autofill.AutofillService" />
+            </intent-filter>
+        </service>
+
     </application>
 
     <instrumentation
diff --git a/tests/autofillservice/res/layout/augmented_autofill_ui.xml b/tests/autofillservice/res/layout/augmented_autofill_ui.xml
new file mode 100644
index 0000000..e6f5a28
--- /dev/null
+++ b/tests/autofillservice/res/layout/augmented_autofill_ui.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/augmentedAutofillUi"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"/>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
index 3ee3e79..bc7e7c1 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
@@ -37,7 +37,7 @@
 /**
   * Base class for all activities in this test suite
   */
-abstract class AbstractAutoFillActivity extends Activity {
+public abstract class AbstractAutoFillActivity extends Activity {
 
     private final CountDownLatch mDestroyedLatch = new CountDownLatch(1);
     private MyAutofillCallback mCallback;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
index 00135d4..c0b2994 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
@@ -24,7 +24,7 @@
 /**
  * Base class for test cases using {@link LoginActivity}.
  */
-abstract class AbstractLoginActivityTestCase
+public abstract class AbstractLoginActivityTestCase
         extends AutoFillServiceTestCase.AutoActivityLaunch<LoginActivity> {
 
     protected LoginActivity mActivity;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index ef5170af..1e1e740 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -65,7 +65,7 @@
  *   <li>Launching the activity used by the test.
  * </ul>
  */
-final class AutoFillServiceTestCase {
+public final class AutoFillServiceTestCase {
 
     /**
      * Base class for all test cases that use an {@link AutofillActivityTestRule} to
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index c03ba04..d68cacf 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -59,7 +59,7 @@
  *               .build());
  * </pre class="prettyprint">
  */
-final class CannedFillResponse {
+public final class CannedFillResponse {
 
     private final ResponseType mResponseType;
     private final List<CannedDataset> mDatasets;
@@ -125,27 +125,27 @@
      * Constant used to pass a {@code null} response to the
      * {@link FillCallback#onSuccess(FillResponse)} method.
      */
-    static final CannedFillResponse NO_RESPONSE =
+    public static final CannedFillResponse NO_RESPONSE =
             new Builder(ResponseType.NULL).build();
 
     /**
      * Constant used to emulate a timeout by not calling any method on {@link FillCallback}.
      */
-    static final CannedFillResponse DO_NOT_REPLY_RESPONSE =
+    public static final CannedFillResponse DO_NOT_REPLY_RESPONSE =
             new Builder(ResponseType.TIMEOUT).build();
 
 
     /**
      * Constant used to call {@link FillCallback#onFailure(CharSequence)} method.
      */
-    static final CannedFillResponse FAIL =
+    public static final CannedFillResponse FAIL =
             new Builder(ResponseType.FAILURE).build();
 
-    String getFailureMessage() {
+    public String getFailureMessage() {
         return mFailureMessage;
     }
 
-    ResponseType getResponseType() {
+    public ResponseType getResponseType() {
         return mResponseType;
     }
 
@@ -153,7 +153,7 @@
      * Creates a new response, replacing the dataset field ids by the real ids from the assist
      * structure.
      */
-    FillResponse asFillResponse(Function<String, ViewNode> nodeResolver) {
+    public FillResponse asFillResponse(Function<String, ViewNode> nodeResolver) {
         final FillResponse.Builder builder = new FillResponse.Builder()
                 .setFlags(mFillResponseFlags);
         if (mDatasets != null) {
@@ -275,14 +275,14 @@
                 + "]";
     }
 
-    enum ResponseType {
+    public enum ResponseType {
         NORMAL,
         NULL,
         TIMEOUT,
         FAILURE
     }
 
-    static class Builder {
+    public static final class Builder {
         private final List<CannedDataset> mDatasets = new ArrayList<>();
         private final ArrayList<Pair<Sanitizer, AutofillId[]>> mSanitizers = new ArrayList<>();
         private final ResponseType mResponseType;
@@ -527,7 +527,7 @@
      *               .build());
      * </pre class="prettyprint">
      */
-    static class CannedDataset {
+    public static class CannedDataset {
         private final Map<String, AutofillValue> mFieldValues;
         private final Map<AutofillId, AutofillValue> mFieldValuesById;
         private final Map<AutofillId, RemoteViews> mFieldPresentationsById;
@@ -611,7 +611,7 @@
                     + ", fieldFilters=" + mFieldFilters + "]";
         }
 
-        static class Builder {
+        public static class Builder {
             private final Map<String, AutofillValue> mFieldValues = new HashMap<>();
             private final Map<AutofillId, AutofillValue> mFieldValuesById = new HashMap<>();
             private final Map<String, RemoteViews> mFieldPresentations = new HashMap<>();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index b6ebd7a..69da062 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -35,9 +35,11 @@
 import android.app.assist.AssistStructure.WindowNode;
 import android.autofillservice.cts.common.OneTimeSettingsListener;
 import android.autofillservice.cts.common.SettingsHelper;
+import android.autofillservice.cts.common.ShellHelper;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.icu.util.Calendar;
 import android.os.Bundle;
@@ -75,35 +77,35 @@
 /**
  * Helper for common funcionalities.
  */
-final class Helper {
+public final class Helper {
 
-    static final String TAG = "AutoFillCtsHelper";
+    public static final String TAG = "AutoFillCtsHelper";
 
-    static final boolean VERBOSE = false;
+    public static final boolean VERBOSE = false;
 
-    static final String MY_PACKAGE = "android.autofillservice.cts";
+    public static final String MY_PACKAGE = "android.autofillservice.cts";
 
-    static final String ID_USERNAME_LABEL = "username_label";
-    static final String ID_USERNAME = "username";
-    static final String ID_PASSWORD_LABEL = "password_label";
-    static final String ID_PASSWORD = "password";
-    static final String ID_LOGIN = "login";
-    static final String ID_OUTPUT = "output";
-    static final String ID_STATIC_TEXT = "static_text";
+    public static final String ID_USERNAME_LABEL = "username_label";
+    public static final String ID_USERNAME = "username";
+    public static final String ID_PASSWORD_LABEL = "password_label";
+    public static final String ID_PASSWORD = "password";
+    public static final String ID_LOGIN = "login";
+    public static final String ID_OUTPUT = "output";
+    public static final String ID_STATIC_TEXT = "static_text";
 
-    static final String NULL_DATASET_ID = null;
+    public static final String NULL_DATASET_ID = null;
 
-    static final char LARGE_STRING_CHAR = '6';
+    public static final char LARGE_STRING_CHAR = '6';
     // NOTE: cannot be much large as it could ANR and fail the test.
-    static final int LARGE_STRING_SIZE = 100_000;
-    static final String LARGE_STRING = com.android.compatibility.common.util.TextUtils
+    public static final int LARGE_STRING_SIZE = 100_000;
+    public static final String LARGE_STRING = com.android.compatibility.common.util.TextUtils
             .repeat(LARGE_STRING_CHAR, LARGE_STRING_SIZE);
 
     /**
      * Can be used in cases where the autofill values is required by irrelevant (like adding a
      * value to an authenticated dataset).
      */
-    static final String UNUSED_AUTOFILL_VALUE = null;
+    public static final String UNUSED_AUTOFILL_VALUE = null;
 
     private static final String ACCELLEROMETER_CHANGE =
             "content insert --uri content://settings/system --bind name:s:accelerometer_rotation "
@@ -116,6 +118,9 @@
             "SETTINGS_SHELL_CMD_TIMEOUT", OneTimeSettingsListener.DEFAULT_TIMEOUT_MS / 2, 2,
             OneTimeSettingsListener.DEFAULT_TIMEOUT_MS);
 
+    private static final String RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION =
+            "config_forceDefaultOrientation";
+
     /**
      * Helper interface used to filter nodes.
      *
@@ -176,12 +181,12 @@
     }
 
     @NonNull
-    static String toString(@NonNull AssistStructure structure) {
+    public static String toString(@NonNull AssistStructure structure) {
         return toString(structure, new StringBuilder());
     }
 
     @Nullable
-    static String toString(@Nullable AutofillValue value) {
+    public static String toString(@Nullable AutofillValue value) {
         if (value == null) return null;
         if (value.isText()) {
             // We don't care about PII...
@@ -194,14 +199,14 @@
     /**
      * Dump the assist structure on logcat.
      */
-    static void dumpStructure(String message, AssistStructure structure) {
+    public static void dumpStructure(String message, AssistStructure structure) {
         Log.i(TAG, toString(structure, new StringBuilder(message)));
     }
 
     /**
      * Dump the contexts on logcat.
      */
-    static void dumpStructure(String message, List<FillContext> contexts) {
+    public static void dumpStructure(String message, List<FillContext> contexts) {
         for (FillContext context : contexts) {
             dumpStructure(message, context.getStructure());
         }
@@ -210,14 +215,14 @@
     /**
      * Dumps the state of the autofill service on logcat.
      */
-    static void dumpAutofillService() {
+    public static void dumpAutofillService() {
         Log.i(TAG, "dumpsys autofill\n\n" + runShellCommand("dumpsys autofill"));
     }
 
     /**
      * Sets whether the user completed the initial setup.
      */
-    static void setUserComplete(Context context, boolean complete) {
+    public static void setUserComplete(Context context, boolean complete) {
         SettingsHelper.syncSet(context, USER_SETUP_COMPLETE, complete ? "1" : null);
     }
 
@@ -255,7 +260,7 @@
      * Appends a field value to a {@link StringBuilder} when it's not {@code null}.
      */
     @NonNull
-    static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+    public static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
             @Nullable Object value) {
         if (value == null) return builder;
 
@@ -275,7 +280,7 @@
      * Appends a field value to a {@link StringBuilder} when it's {@code true}.
      */
     @NonNull
-    static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+    public static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
             boolean value) {
         if (value) {
             builder.append(", ").append(field);
@@ -286,7 +291,7 @@
     /**
      * Gets a node if it matches the filter criteria for the given id.
      */
-    static ViewNode findNodeByFilter(@NonNull AssistStructure structure, @NonNull Object id,
+    public static ViewNode findNodeByFilter(@NonNull AssistStructure structure, @NonNull Object id,
             @NonNull NodeFilter<ViewNode> filter) {
         Log.v(TAG, "Parsing request for activity " + structure.getActivityComponent());
         final int nodes = structure.getWindowNodeCount();
@@ -304,7 +309,7 @@
     /**
      * Gets a node if it matches the filter criteria for the given id.
      */
-    static ViewNode findNodeByFilter(@NonNull List<FillContext> contexts, @NonNull Object id,
+    public static ViewNode findNodeByFilter(@NonNull List<FillContext> contexts, @NonNull Object id,
             @NonNull NodeFilter<ViewNode> filter) {
         for (FillContext context : contexts) {
             ViewNode node = findNodeByFilter(context.getStructure(), id, filter);
@@ -318,7 +323,7 @@
     /**
      * Gets a node if it matches the filter criteria for the given id.
      */
-    static ViewNode findNodeByFilter(@NonNull ViewNode node, @NonNull Object id,
+    public static ViewNode findNodeByFilter(@NonNull ViewNode node, @NonNull Object id,
             @NonNull NodeFilter<ViewNode> filter) {
         if (filter.matches(node, id)) {
             return node;
@@ -338,42 +343,42 @@
     /**
      * Gets a node given its Android resource id, or {@code null} if not found.
      */
-    static ViewNode findNodeByResourceId(AssistStructure structure, String resourceId) {
+    public static ViewNode findNodeByResourceId(AssistStructure structure, String resourceId) {
         return findNodeByFilter(structure, resourceId, RESOURCE_ID_FILTER);
     }
 
     /**
      * Gets a node given its Android resource id, or {@code null} if not found.
      */
-    static ViewNode findNodeByResourceId(List<FillContext> contexts, String resourceId) {
+    public static ViewNode findNodeByResourceId(List<FillContext> contexts, String resourceId) {
         return findNodeByFilter(contexts, resourceId, RESOURCE_ID_FILTER);
     }
 
     /**
      * Gets a node given its Android resource id, or {@code null} if not found.
      */
-    static ViewNode findNodeByResourceId(ViewNode node, String resourceId) {
+    public static ViewNode findNodeByResourceId(ViewNode node, String resourceId) {
         return findNodeByFilter(node, resourceId, RESOURCE_ID_FILTER);
     }
 
     /**
      * Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
      */
-    static ViewNode findNodeByHtmlName(AssistStructure structure, String htmlName) {
+    public static ViewNode findNodeByHtmlName(AssistStructure structure, String htmlName) {
         return findNodeByFilter(structure, htmlName, HTML_NAME_FILTER);
     }
 
     /**
      * Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
      */
-    static ViewNode findNodeByHtmlName(List<FillContext> contexts, String htmlName) {
+    public static ViewNode findNodeByHtmlName(List<FillContext> contexts, String htmlName) {
         return findNodeByFilter(contexts, htmlName, HTML_NAME_FILTER);
     }
 
     /**
      * Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
      */
-    static ViewNode findNodeByHtmlName(ViewNode node, String htmlName) {
+    public static ViewNode findNodeByHtmlName(ViewNode node, String htmlName) {
         return findNodeByFilter(node, htmlName, HTML_NAME_FILTER);
     }
 
@@ -381,7 +386,7 @@
      * Gets a node given the value of its (single) autofill hint property, or {@code null} if not
      * found.
      */
-    static ViewNode findNodeByAutofillHint(ViewNode node, String hint) {
+    public static ViewNode findNodeByAutofillHint(ViewNode node, String hint) {
         return findNodeByFilter(node, hint, AUTOFILL_HINT_FILTER);
     }
 
@@ -389,7 +394,7 @@
      * Gets a node given the name of its HTML INPUT tag or Android resoirce id, or {@code null} if
      * not found.
      */
-    static ViewNode findNodeByHtmlNameOrResourceId(List<FillContext> contexts, String id) {
+    public static ViewNode findNodeByHtmlNameOrResourceId(List<FillContext> contexts, String id) {
         return findNodeByFilter(contexts, id, HTML_NAME_OR_RESOURCE_ID_FILTER);
     }
 
@@ -397,7 +402,7 @@
      * Gets the {@code name} attribute of a node representing an HTML input tag.
      */
     @Nullable
-    static String getHtmlName(@NonNull ViewNode node) {
+    public static String getHtmlName(@NonNull ViewNode node) {
         final HtmlInfo htmlInfo = node.getHtmlInfo();
         if (htmlInfo == null) {
             return null;
@@ -419,21 +424,21 @@
     /**
      * Gets a node given its expected text, or {@code null} if not found.
      */
-    static ViewNode findNodeByText(AssistStructure structure, String text) {
+    public static ViewNode findNodeByText(AssistStructure structure, String text) {
         return findNodeByFilter(structure, text, TEXT_FILTER);
     }
 
     /**
      * Gets a node given its expected text, or {@code null} if not found.
      */
-    static ViewNode findNodeByText(ViewNode node, String text) {
+    public static ViewNode findNodeByText(ViewNode node, String text) {
         return findNodeByFilter(node, text, TEXT_FILTER);
     }
 
     /**
      * Gets a view that contains the an autofill hint, or {@code null} if not found.
      */
-    static View findViewByAutofillHint(Activity activity, String hint) {
+    public static View findViewByAutofillHint(Activity activity, String hint) {
         final View rootView = activity.getWindow().getDecorView().getRootView();
         return findViewByAutofillHint(rootView, hint);
     }
@@ -442,7 +447,7 @@
      * Gets a view (or a descendant of it) that contains the an autofill hint, or {@code null} if
      * not found.
      */
-    static View findViewByAutofillHint(View view, String hint) {
+    public static View findViewByAutofillHint(View view, String hint) {
         if (AUTOFILL_HINT_VIEW_FILTER.matches(view, hint)) return view;
         if ((view instanceof ViewGroup)) {
             final ViewGroup group = (ViewGroup) view;
@@ -458,14 +463,14 @@
      * Gets a view (or a descendant of it) that has the given {@code id}, or {@code null} if
      * not found.
      */
-    static ViewNode findNodeByAutofillId(AssistStructure structure, AutofillId id) {
+    public static ViewNode findNodeByAutofillId(AssistStructure structure, AutofillId id) {
         return findNodeByFilter(structure, id, AUTOFILL_ID_FILTER);
     }
 
     /**
      * Asserts a text-based node is sanitized.
      */
-    static void assertTextIsSanitized(ViewNode node) {
+    public static void assertTextIsSanitized(ViewNode node) {
         final CharSequence text = node.getText();
         final String resourceId = node.getIdEntry();
         if (!TextUtils.isEmpty(text)) {
@@ -480,7 +485,7 @@
         assertThat(node.getTextIdEntry()).isNull();
     }
 
-    static void assertNodeHasNoAutofillValue(ViewNode node) {
+    public static void assertNodeHasNoAutofillValue(ViewNode node) {
         final AutofillValue value = node.getAutofillValue();
         if (value != null) {
             final String text = value.isText() ? value.getTextValue().toString() : "N/A";
@@ -491,7 +496,7 @@
     /**
      * Asserts the contents of a text-based node that is also auto-fillable.
      */
-    static void assertTextOnly(ViewNode node, String expectedValue) {
+    public static void assertTextOnly(ViewNode node, String expectedValue) {
         assertText(node, expectedValue, false);
         assertNotFromResources(node);
     }
@@ -499,7 +504,8 @@
     /**
      * Asserts the contents of a text-based node that is also auto-fillable.
      */
-    static void assertTextOnly(AssistStructure structure, String resourceId, String expectedValue) {
+    public static void assertTextOnly(AssistStructure structure, String resourceId,
+            String expectedValue) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertText(node, expectedValue, false);
         assertNotFromResources(node);
@@ -508,7 +514,7 @@
     /**
      * Asserts the contents of a text-based node that is also auto-fillable.
      */
-    static void assertTextAndValue(ViewNode node, String expectedValue) {
+    public static void assertTextAndValue(ViewNode node, String expectedValue) {
         assertText(node, expectedValue, true);
         assertNotFromResources(node);
     }
@@ -516,7 +522,7 @@
     /**
      * Asserts a text-based node exists and verify its values.
      */
-    static ViewNode assertTextAndValue(AssistStructure structure, String resourceId,
+    public static ViewNode assertTextAndValue(AssistStructure structure, String resourceId,
             String expectedValue) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertTextAndValue(node, expectedValue);
@@ -526,7 +532,7 @@
     /**
      * Asserts a text-based node exists and is sanitized.
      */
-    static ViewNode assertValue(AssistStructure structure, String resourceId,
+    public static ViewNode assertValue(AssistStructure structure, String resourceId,
             String expectedValue) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertTextValue(node, expectedValue);
@@ -536,7 +542,7 @@
     /**
      * Asserts the values of a text-based node whose string come from resoruces.
      */
-    static ViewNode assertTextFromResouces(AssistStructure structure, String resourceId,
+    public static ViewNode assertTextFromResouces(AssistStructure structure, String resourceId,
             String expectedValue, boolean isAutofillable, String expectedTextIdEntry) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertText(node, expectedValue, isAutofillable);
@@ -561,7 +567,7 @@
     /**
      * Asserts the auto-fill value of a text-based node.
      */
-    static ViewNode assertTextValue(ViewNode node, String expectedText) {
+    public static ViewNode assertTextValue(ViewNode node, String expectedText) {
         final AutofillValue value = node.getAutofillValue();
         final AutofillId id = node.getAutofillId();
         assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -574,7 +580,7 @@
     /**
      * Asserts the auto-fill value of a list-based node.
      */
-    static ViewNode assertListValue(ViewNode node, int expectedIndex) {
+    public static ViewNode assertListValue(ViewNode node, int expectedIndex) {
         final AutofillValue value = node.getAutofillValue();
         final AutofillId id = node.getAutofillId();
         assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -587,7 +593,7 @@
     /**
      * Asserts the auto-fill value of a toggle-based node.
      */
-    static void assertToggleValue(ViewNode node, boolean expectedToggle) {
+    public static void assertToggleValue(ViewNode node, boolean expectedToggle) {
         final AutofillValue value = node.getAutofillValue();
         final AutofillId id = node.getAutofillId();
         assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -599,7 +605,8 @@
     /**
      * Asserts the auto-fill value of a date-based node.
      */
-    static void assertDateValue(Object object, AutofillValue value, int year, int month, int day) {
+    public static void assertDateValue(Object object, AutofillValue value, int year, int month,
+            int day) {
         assertWithMessage("null autofill value on %s", object).that(value).isNotNull();
         assertWithMessage("wrong autofill type on %s", object).that(value.isDate()).isTrue();
 
@@ -617,14 +624,14 @@
     /**
      * Asserts the auto-fill value of a date-based node.
      */
-    static void assertDateValue(ViewNode node, int year, int month, int day) {
+    public static void assertDateValue(ViewNode node, int year, int month, int day) {
         assertDateValue(node, node.getAutofillValue(), year, month, day);
     }
 
     /**
      * Asserts the auto-fill value of a date-based view.
      */
-    static void assertDateValue(View view, int year, int month, int day) {
+    public static void assertDateValue(View view, int year, int month, int day) {
         assertDateValue(view, view.getAutofillValue(), year, month, day);
     }
 
@@ -647,21 +654,21 @@
     /**
      * Asserts the auto-fill value of a time-based node.
      */
-    static void assertTimeValue(ViewNode node, int hour, int minute) {
+    public static void assertTimeValue(ViewNode node, int hour, int minute) {
         assertTimeValue(node, node.getAutofillValue(), hour, minute);
     }
 
     /**
      * Asserts the auto-fill value of a time-based view.
      */
-    static void assertTimeValue(View view, int hour, int minute) {
+    public static void assertTimeValue(View view, int hour, int minute) {
         assertTimeValue(view, view.getAutofillValue(), hour, minute);
     }
 
     /**
      * Asserts a text-based node exists and is sanitized.
      */
-    static ViewNode assertTextIsSanitized(AssistStructure structure, String resourceId) {
+    public static ViewNode assertTextIsSanitized(AssistStructure structure, String resourceId) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertWithMessage("no ViewNode with id %s", resourceId).that(node).isNotNull();
         assertTextIsSanitized(node);
@@ -671,7 +678,7 @@
     /**
      * Asserts a list-based node exists and is sanitized.
      */
-    static void assertListValueIsSanitized(AssistStructure structure, String resourceId) {
+    public static void assertListValueIsSanitized(AssistStructure structure, String resourceId) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertWithMessage("no ViewNode with id %s", resourceId).that(node).isNotNull();
         assertTextIsSanitized(node);
@@ -680,7 +687,7 @@
     /**
      * Asserts a toggle node exists and is sanitized.
      */
-    static void assertToggleIsSanitized(AssistStructure structure, String resourceId) {
+    public static void assertToggleIsSanitized(AssistStructure structure, String resourceId) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         assertNodeHasNoAutofillValue(node);
         assertWithMessage("ViewNode %s should not be checked", resourceId).that(node.isChecked())
@@ -690,7 +697,8 @@
     /**
      * Asserts a node exists and has the {@code expected} number of children.
      */
-    static void assertNumberOfChildren(AssistStructure structure, String resourceId, int expected) {
+    public static void assertNumberOfChildren(AssistStructure structure, String resourceId,
+            int expected) {
         final ViewNode node = findNodeByResourceId(structure, resourceId);
         final int actual = node.getChildCount();
         if (actual != expected) {
@@ -703,7 +711,7 @@
     /**
      * Asserts the number of children in the Assist structure.
      */
-    static void assertNumberOfChildren(AssistStructure structure, int expected) {
+    public static void assertNumberOfChildren(AssistStructure structure, int expected) {
         assertWithMessage("wrong number of nodes").that(structure.getWindowNodeCount())
                 .isEqualTo(1);
         final int actual = getNumberNodes(structure);
@@ -717,7 +725,7 @@
     /**
      * Gets the total number of nodes in an structure.
      */
-    static int getNumberNodes(AssistStructure structure) {
+    public static int getNumberNodes(AssistStructure structure) {
         int count = 0;
         final int nodes = structure.getWindowNodeCount();
         for (int i = 0; i < nodes; i++) {
@@ -731,7 +739,7 @@
     /**
      * Gets the total number of nodes in an node, including all descendants and the node itself.
      */
-    static int getNumberNodes(ViewNode node) {
+    public static int getNumberNodes(ViewNode node) {
         int count = 1;
         final int childrenSize = node.getChildCount();
         if (childrenSize > 0) {
@@ -746,7 +754,7 @@
      * Creates an array of {@link AutofillId} mapped from the {@code structure} nodes with the given
      * {@code resourceIds}.
      */
-    static AutofillId[] getAutofillIds(Function<String, ViewNode> nodeResolver,
+    public static AutofillId[] getAutofillIds(Function<String, ViewNode> nodeResolver,
             String[] resourceIds) {
         if (resourceIds == null) return null;
 
@@ -767,7 +775,8 @@
      * Get an {@link AutofillId} mapped from the {@code structure} node with the given
      * {@code resourceId}.
      */
-    static AutofillId getAutofillId(Function<String, ViewNode> nodeResolver, String resourceId) {
+    public static AutofillId getAutofillId(Function<String, ViewNode> nodeResolver,
+            String resourceId) {
         if (resourceId == null) return null;
 
         final ViewNode node = nodeResolver.apply(resourceId);
@@ -837,7 +846,35 @@
      * Checks if screen orientation can be changed.
      */
     public static boolean isRotationSupported(Context context) {
-        return !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+        if (!isScreenRotationSupported(context)) {
+            Log.v(TAG, "isRotationSupported(): screen rotation not supported");
+            return false;
+        }
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            Log.v(TAG, "isRotationSupported(): has leanback feature");
+            return false;
+        }
+        return true;
+    }
+
+     /**
+     * Returns {@code true} if display rotation is supported, {@code false} otherwise.
+     */
+    private static boolean isScreenRotationSupported(Context context) {
+        try {
+            return !getBoolean(context, RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION);
+        } catch (Resources.NotFoundException e) {
+            Log.d(TAG, "Resource not found: "
+                    + RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION
+                    + ". Assume rotation supported");
+            return true;
+        }
+    }
+
+    private static boolean getBoolean(Context context, String id) {
+        final Resources resources = context.getResources();
+        final int booleanId = resources.getIdentifier(id, "bool", "android");
+        return resources.getBoolean(booleanId);
     }
 
     /**
@@ -1288,7 +1325,7 @@
     }
 
     @Nullable
-    public static File dumpBitmap(@NonNull Bitmap bitmap, @NonNull File file) throws IOException {
+    public static File dumpBitmap(@NonNull Bitmap bitmap, @NonNull File file) {
         Log.i(TAG, "Dumping bitmap at " + file);
         BitmapUtils.saveBitmap(bitmap, file.getParent(), file.getName());
         return file;
@@ -1340,6 +1377,24 @@
         assertThat(string.charAt(LARGE_STRING_SIZE - 1)).isEqualTo(LARGE_STRING_CHAR);
     }
 
+    /**
+     * Allows the test to draw overlaid windows.
+     *
+     * <p>Should call {@link #disallowOverlays()} afterwards.
+     */
+    public static void allowOverlays() {
+        ShellHelper.setOverlayPermissions(MY_PACKAGE, true);
+    }
+
+    /**
+     * Disallow the test to draw overlaid windows.
+     *
+     * <p>Should call {@link #disallowOverlays()} afterwards.
+     */
+    public static void disallowOverlays() {
+        ShellHelper.setOverlayPermissions(MY_PACKAGE, false);
+    }
+
     private Helper() {
         throw new UnsupportedOperationException("contain static methods only");
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index 7309db6..4062817 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -259,7 +259,7 @@
      * was replied with a {@code null} response) - if a text needs to block until the service
      * receives a callback, it should use {@link Replier#getNextFillRequest()} instead.
      */
-    static void waitUntilConnected() throws Exception {
+    public static void waitUntilConnected() throws Exception {
         waitConnectionState(CONNECTION_TIMEOUT, true);
     }
 
@@ -269,7 +269,7 @@
      * <p>This method is useful on tests that explicitly verifies the connection, but should be
      * avoided in other tests, as it adds extra time to the test execution.
      */
-    static void waitUntilDisconnected() throws Exception {
+    public static void waitUntilDisconnected() throws Exception {
         waitConnectionState(IDLE_UNBIND_TIMEOUT, false);
     }
 
@@ -297,7 +297,7 @@
      * {@link AutofillService#onFillRequest(android.service.autofill.FillRequest,
      * CancellationSignal, FillCallback)} that can be asserted at the end of a test case.
      */
-    static final class FillRequest {
+    public static final class FillRequest {
         final AssistStructure structure;
         final List<FillContext> contexts;
         final Bundle data;
@@ -327,7 +327,7 @@
      * {@link AutofillService#onSaveRequest(android.service.autofill.SaveRequest, SaveCallback)}
      * that can be asserted at the end of a test case.
      */
-    static final class SaveRequest {
+    public static final class SaveRequest {
         public final List<FillContext> contexts;
         public final AssistStructure structure;
         public final Bundle data;
@@ -359,7 +359,7 @@
      * CancellationSignal, FillCallback)}
      * on behalf of a unit test method.
      */
-    static final class Replier {
+    public static final class Replier {
 
         private final BlockingQueue<CannedFillResponse> mResponses = new LinkedBlockingQueue<>();
         private final BlockingQueue<FillRequest> mFillRequests = new LinkedBlockingQueue<>();
@@ -388,7 +388,8 @@
         /**
          * Gets the exceptions thrown asynchronously, if any.
          */
-        @Nullable List<Throwable> getExceptions() {
+        @Nullable
+        public List<Throwable> getExceptions() {
             return mExceptions;
         }
 
@@ -405,7 +406,7 @@
          * Sets the expectation for the next {@code onFillRequest} as {@link FillResponse} with just
          * one {@link Dataset}.
          */
-        Replier addResponse(CannedDataset dataset) {
+        public Replier addResponse(CannedDataset dataset) {
             return addResponse(new CannedFillResponse.Builder()
                     .addDataset(dataset)
                     .build());
@@ -414,7 +415,7 @@
         /**
          * Sets the expectation for the next {@code onFillRequest}.
          */
-        Replier addResponse(CannedFillResponse response) {
+        public Replier addResponse(CannedFillResponse response) {
             if (response == null) {
                 throw new IllegalArgumentException("Cannot be null - use NO_RESPONSE instead");
             }
@@ -426,17 +427,15 @@
          * Sets the {@link IntentSender} that is passed to
          * {@link SaveCallback#onSuccess(IntentSender)}.
          */
-        Replier setOnSave(IntentSender intentSender) {
+        public Replier setOnSave(IntentSender intentSender) {
             mOnSaveIntentSender = intentSender;
             return this;
         }
 
         /**
          * Gets the next fill request, in the order received.
-         *
-         * <p>Typically called at the end of a test case, to assert the initial request.
          */
-        FillRequest getNextFillRequest() {
+        public FillRequest getNextFillRequest() {
             FillRequest request;
             try {
                 request = mFillRequests.poll(FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
@@ -457,7 +456,7 @@
          * <p>Should only be called in cases where it's not expected to be called, as it will
          * sleep for a few ms.
          */
-        void assertOnFillRequestNotCalled() {
+        public void assertOnFillRequestNotCalled() {
             SystemClock.sleep(FILL_TIMEOUT.getMaxValue());
             assertThat(mFillRequests).isEmpty();
         }
@@ -468,7 +467,7 @@
          * received by the service were properly {@link #getNextFillRequest() handled} by the test
          * case.
          */
-        void assertNoUnhandledFillRequests() {
+        public void assertNoUnhandledFillRequests() {
             if (mFillRequests.isEmpty()) return; // Good job, test case!
 
             if (!mReportUnhandledFillRequest) {
@@ -486,7 +485,7 @@
         /**
          * Gets the current number of unhandled requests.
          */
-        int getNumberUnhandledFillRequests() {
+        public int getNumberUnhandledFillRequests() {
             return mFillRequests.size();
         }
 
@@ -495,7 +494,7 @@
          *
          * <p>Typically called at the end of a test case, to assert the initial request.
          */
-        SaveRequest getNextSaveRequest() {
+        public SaveRequest getNextSaveRequest() {
             SaveRequest request;
             try {
                 request = mSaveRequests.poll(SAVE_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
@@ -515,7 +514,7 @@
          * save requests} received by the service were properly
          * {@link #getNextFillRequest() handled} by the test case.
          */
-        void assertNoUnhandledSaveRequests() {
+        public void assertNoUnhandledSaveRequests() {
             if (mSaveRequests.isEmpty()) return; // Good job, test case!
 
             if (!mReportUnhandledSaveRequest) {
@@ -533,7 +532,7 @@
         /**
          * Resets its internal state.
          */
-        void reset() {
+        public void reset() {
             mResponses.clear();
             mFillRequests.clear();
             mSaveRequests.clear();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index 8690204..939792c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -50,10 +50,10 @@
     private static String WELCOME_TEMPLATE = "Welcome to the new activity, %s!";
     private static final long LOGIN_TIMEOUT_MS = 1000;
 
-    static final String ID_USERNAME_CONTAINER = "username_container";
-    static final String AUTHENTICATION_MESSAGE = "Authentication failed. D'OH!";
-    static final String BACKDOOR_USERNAME = "LemmeIn";
-    static final String BACKDOOR_PASSWORD_SUBSTRING = "pass";
+    public static final String ID_USERNAME_CONTAINER = "username_container";
+    public static final String AUTHENTICATION_MESSAGE = "Authentication failed. D'OH!";
+    public static final String BACKDOOR_USERNAME = "LemmeIn";
+    public static final String BACKDOOR_PASSWORD_SUBSTRING = "pass";
 
     private LinearLayout mUsernameContainer;
     private TextView mUsernameLabel;
@@ -74,7 +74,7 @@
     /**
      * Gets the expected welcome message for a given username.
      */
-    static String getWelcomeMessage(String username) {
+    public static String getWelcomeMessage(String username) {
         return String.format(WELCOME_TEMPLATE,  username);
     }
 
@@ -157,7 +157,7 @@
      * Sets the expectation for an autofill request (for all fields), so it can be asserted through
      * {@link #assertAutoFilled()} later.
      */
-    void expectAutoFill(String username, String password) {
+    public void expectAutoFill(String username, String password) {
         mExpectation = new FillExpectation(username, password);
         mUsernameEditText.addTextChangedListener(mExpectation.ccUsernameWatcher);
         mPasswordEditText.addTextChangedListener(mExpectation.ccPasswordWatcher);
@@ -167,7 +167,7 @@
      * Sets the expectation for an autofill request (for username only), so it can be asserted
      * through {@link #assertAutoFilled()} later.
      */
-    void expectAutoFill(String username) {
+    public void expectAutoFill(String username) {
         mExpectation = new FillExpectation(username);
         mUsernameEditText.addTextChangedListener(mExpectation.ccUsernameWatcher);
     }
@@ -176,7 +176,7 @@
      * Sets the expectation for an autofill request (for password only), so it can be asserted
      * through {@link #assertAutoFilled()} later.
      */
-    void expectPasswordAutoFill(String password) {
+    public void expectPasswordAutoFill(String password) {
         mExpectation = new FillExpectation(null, password);
         mPasswordEditText.addTextChangedListener(mExpectation.ccPasswordWatcher);
     }
@@ -185,7 +185,7 @@
      * Asserts the activity was auto-filled with the values passed to
      * {@link #expectAutoFill(String, String)}.
      */
-    void assertAutoFilled() throws Exception {
+    public void assertAutoFilled() throws Exception {
         assertWithMessage("expectAutoFill() not called").that(mExpectation).isNotNull();
         if (mExpectation.ccUsernameWatcher != null) {
             mExpectation.ccUsernameWatcher.assertAutoFilled();
@@ -195,25 +195,25 @@
         }
     }
 
-    void forceAutofillOnUsername() {
+    public void forceAutofillOnUsername() {
         syncRunOnUiThread(() -> getAutofillManager().requestAutofill(mUsernameEditText));
     }
 
-    void forceAutofillOnPassword() {
+    public void forceAutofillOnPassword() {
         syncRunOnUiThread(() -> getAutofillManager().requestAutofill(mPasswordEditText));
     }
 
     /**
      * Visits the {@code username_label} in the UiThread.
      */
-    void onUsernameLabel(Visitor<TextView> v) {
+    public void onUsernameLabel(Visitor<TextView> v) {
         syncRunOnUiThread(() -> v.visit(mUsernameLabel));
     }
 
     /**
      * Visits the {@code username} in the UiThread.
      */
-    void onUsername(Visitor<EditText> v) {
+    public void onUsername(Visitor<EditText> v) {
         syncRunOnUiThread(() -> v.visit(mUsernameEditText));
     }
 
@@ -227,42 +227,42 @@
     /**
      * Gets the {@code username_label} view.
      */
-    TextView getUsernameLabel() {
+    public TextView getUsernameLabel() {
         return mUsernameLabel;
     }
 
     /**
      * Gets the {@code username} view.
      */
-    EditText getUsername() {
+    public EditText getUsername() {
         return mUsernameEditText;
     }
 
     /**
      * Visits the {@code password_label} in the UiThread.
      */
-    void onPasswordLabel(Visitor<TextView> v) {
+    public void onPasswordLabel(Visitor<TextView> v) {
         syncRunOnUiThread(() -> v.visit(mPasswordLabel));
     }
 
     /**
      * Visits the {@code password} in the UiThread.
      */
-    void onPassword(Visitor<EditText> v) {
+    public void onPassword(Visitor<EditText> v) {
         syncRunOnUiThread(() -> v.visit(mPasswordEditText));
     }
 
     /**
      * Gets the {@code password} view.
      */
-    EditText getPassword() {
+    public EditText getPassword() {
         return mPasswordEditText;
     }
 
     /**
      * Taps the login button in the UI thread.
      */
-    String tapLogin() throws Exception {
+    public String tapLogin() throws Exception {
         mLoginLatch = new CountDownLatch(1);
         syncRunOnUiThread(() -> mLoginButton.performClick());
         boolean called = mLoginLatch.await(LOGIN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
@@ -274,7 +274,7 @@
     /**
      * Taps the save button in the UI thread.
      */
-    void tapSave() throws Exception {
+    public void tapSave() throws Exception {
         syncRunOnUiThread(() -> mSaveButton.performClick());
     }
 
@@ -288,7 +288,7 @@
     /**
      * Sets the window flags.
      */
-    void setFlags(int flags) {
+    public void setFlags(int flags) {
         Log.d(TAG, "setFlags():" + flags);
         syncRunOnUiThread(() -> getWindow().setFlags(flags, flags));
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 5b42ad8..5edfb53 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -23,12 +23,14 @@
 import static android.autofillservice.cts.Helper.ID_PASSWORD_LABEL;
 import static android.autofillservice.cts.Helper.ID_USERNAME;
 import static android.autofillservice.cts.Helper.ID_USERNAME_LABEL;
+import static android.autofillservice.cts.Helper.allowOverlays;
 import static android.autofillservice.cts.Helper.assertHasFlags;
 import static android.autofillservice.cts.Helper.assertNumberOfChildren;
 import static android.autofillservice.cts.Helper.assertTextAndValue;
 import static android.autofillservice.cts.Helper.assertTextIsSanitized;
 import static android.autofillservice.cts.Helper.assertTextOnly;
 import static android.autofillservice.cts.Helper.assertValue;
+import static android.autofillservice.cts.Helper.disallowOverlays;
 import static android.autofillservice.cts.Helper.dumpStructure;
 import static android.autofillservice.cts.Helper.findNodeByResourceId;
 import static android.autofillservice.cts.Helper.isAutofillWindowFullScreen;
@@ -41,7 +43,6 @@
 import static android.autofillservice.cts.LoginActivity.BACKDOOR_USERNAME;
 import static android.autofillservice.cts.LoginActivity.ID_USERNAME_CONTAINER;
 import static android.autofillservice.cts.LoginActivity.getWelcomeMessage;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.autofillservice.cts.common.ShellHelper.sendKeyEvent;
 import static android.autofillservice.cts.common.ShellHelper.tap;
 import static android.content.Context.CLIPBOARD_SERVICE;
@@ -943,7 +944,7 @@
         final View[] overlay = new View[1];
         try {
             // Allow ourselves to add overlays
-            runShellCommand("appops set %s SYSTEM_ALERT_WINDOW allow", mPackageName);
+            allowOverlays();
 
             // Make sure the fill UI is shown.
             mUiBot.assertDatasets("The Dude");
@@ -1013,7 +1014,7 @@
         } finally {
             try {
                 // Make sure we can no longer add overlays
-                runShellCommand("appops set %s SYSTEM_ALERT_WINDOW ignore", mPackageName);
+                disallowOverlays();
                 // Make sure the overlay is removed
                 mActivity.runOnUiThread(() -> {
                     WindowManager windowManager = mContext.getSystemService(WindowManager.class);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java b/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
index 0b055e0..9ba3f6b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
@@ -27,15 +27,16 @@
  * Custom {@link android.os.CancellationSignal.OnCancelListener} used to assert that
  * {@link android.os.CancellationSignal.OnCancelListener} was called, and just once.
  */
-final class OneTimeCancellationSignalListener implements CancellationSignal.OnCancelListener {
+public final class OneTimeCancellationSignalListener
+        implements CancellationSignal.OnCancelListener {
     private final CountDownLatch mLatch = new CountDownLatch(1);
     private final long mTimeoutMs;
 
-    OneTimeCancellationSignalListener(long timeoutMs) {
+    public OneTimeCancellationSignalListener(long timeoutMs) {
         mTimeoutMs = timeoutMs;
     }
 
-    void assertOnCancelCalled() throws Exception {
+    public void assertOnCancelCalled() throws Exception {
         final boolean called = mLatch.await(mTimeoutMs, TimeUnit.MILLISECONDS);
         assertWithMessage("Timeout (%s ms) waiting for onCancel()", mTimeoutMs)
                 .that(called).isTrue();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 3c520bc..85e8983 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -67,7 +67,7 @@
 /**
  * Helper for UI-related needs.
  */
-final class UiBot {
+public final class UiBot {
 
     private static final String TAG = "AutoFillCtsUiBot";
 
@@ -130,11 +130,11 @@
 
     private boolean mOkToCallAssertNoDatasets;
 
-    UiBot() {
+    public UiBot() {
         this(UI_TIMEOUT);
     }
 
-    UiBot(Timeout defaultTimeout) {
+    public UiBot(Timeout defaultTimeout) {
         mDefaultTimeout = defaultTimeout;
         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
         mDevice = UiDevice.getInstance(instrumentation);
@@ -143,14 +143,14 @@
         mAutoman = instrumentation.getUiAutomation();
     }
 
-    void waitForIdle() {
+    public void waitForIdle() {
         final long before = SystemClock.elapsedRealtimeNanos();
         mDevice.waitForIdle();
         final float delta = ((float) (SystemClock.elapsedRealtimeNanos() - before)) / 1_000_000;
         Log.v(TAG, "device idle in " + delta + "ms");
     }
 
-    void reset() {
+    public void reset() {
         mOkToCallAssertNoDatasets = false;
     }
 
@@ -159,7 +159,7 @@
      * {@code AssumptionViolatedException} if it doesn't (so the test is skiped by the JUnit
      * Runner).
      */
-    void assumeMinimumResolution(int minSize) {
+    public void assumeMinimumResolution(int minSize) {
         final int width = mDevice.getDisplayWidth();
         final int heigth = mDevice.getDisplayHeight();
         final int min = Math.min(width, heigth);
@@ -174,7 +174,7 @@
      *
      * When called, test must call <p>{@link #resetScreenResolution()} in a {@code finally} block.
      */
-    void setScreenResolution() {
+    public void setScreenResolution() {
         assumeMinimumResolution(500);
 
         runShellCommand("wm size 1080x1920");
@@ -186,7 +186,7 @@
      *
      * <p>Should always be called after {@link #setScreenResolution()}.
      */
-    void resetScreenResolution() {
+    public void resetScreenResolution() {
         runShellCommand("wm density reset");
         runShellCommand("wm size reset");
     }
@@ -198,7 +198,7 @@
      * dataset picker is shown - if that's not the case, call
      * {@link #assertNoDatasetsEver()} instead.
      */
-    void assertNoDatasets() throws Exception {
+    public void assertNoDatasets() throws Exception {
         if (!mOkToCallAssertNoDatasets) {
             throw new IllegalStateException(
                     "Cannot call assertNoDatasets() without calling assertDatasets first");
@@ -213,7 +213,7 @@
      * <p>This method is slower than {@link #assertNoDatasets()} and should only be called in the
      * cases where the dataset picker was not previous shown.
      */
-    void assertNoDatasetsEver() throws Exception {
+    public void assertNoDatasetsEver() throws Exception {
         assertNeverShown("dataset picker", DATASET_PICKER_SELECTOR,
                 DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
     }
@@ -223,7 +223,7 @@
      *
      * @return the dataset picker object.
      */
-    UiObject2 assertDatasets(String...names) throws Exception {
+    public UiObject2 assertDatasets(String...names) throws Exception {
         // TODO: change run() so it can rethrow the original message
         return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
             final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
@@ -245,7 +245,7 @@
      *
      * @return the dataset picker object.
      */
-    UiObject2 assertDatasetsContains(String...names) throws Exception {
+    public UiObject2 assertDatasetsContains(String...names) throws Exception {
         // TODO: change run() so it can rethrow the original message
         return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
             final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
@@ -268,7 +268,7 @@
      *
      * @return the dataset picker object.
      */
-    UiObject2 assertDatasetsWithBorders(String header, String footer, String...names)
+    public UiObject2 assertDatasetsWithBorders(String header, String footer, String...names)
             throws Exception {
         final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
         final List<String> expectedChild = new ArrayList<>();
@@ -295,7 +295,7 @@
     /**
      * Gets the text of this object children.
      */
-    List<String> getChildrenAsText(UiObject2 object) {
+    public List<String> getChildrenAsText(UiObject2 object) {
         final List<String> list = new ArrayList<>();
         getChildrenAsText(object, list);
         return list;
@@ -314,7 +314,7 @@
     /**
      * Selects a dataset that should be visible in the floating UI.
      */
-    void selectDataset(String name) throws Exception {
+    public void selectDataset(String name) throws Exception {
         final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
         selectDataset(picker, name);
     }
@@ -322,7 +322,7 @@
     /**
      * Selects a dataset that should be visible in the floating UI.
      */
-    void selectDataset(UiObject2 picker, String name) {
+    public void selectDataset(UiObject2 picker, String name) {
         final UiObject2 dataset = picker.findObject(By.text(name));
         if (dataset == null) {
             throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(picker));
@@ -336,7 +336,7 @@
      * <p><b>NOTE:</b> when selecting an option in dataset picker is shown, prefer
      * {@link #selectDataset(String)}.
      */
-    void selectByText(String name) throws Exception {
+    public void selectByText(String name) throws Exception {
         Log.v(TAG, "selectByText(): " + name);
 
         final UiObject2 object = waitForObject(By.text(name));
@@ -394,7 +394,7 @@
     /**
      * Checks if a View with a certain text exists.
      */
-    boolean hasViewWithText(String name) {
+    public boolean hasViewWithText(String name) {
         Log.v(TAG, "hasViewWithText(): " + name);
 
         return mDevice.findObject(By.text(name)) != null;
@@ -403,7 +403,7 @@
     /**
      * Selects a view by id.
      */
-    UiObject2 selectByRelativeId(String id) throws Exception {
+    public UiObject2 selectByRelativeId(String id) throws Exception {
         Log.v(TAG, "selectByRelativeId(): " + id);
         UiObject2 object = waitForObject(By.res(mPackageName, id));
         object.click();
@@ -413,7 +413,7 @@
     /**
      * Asserts the id is shown on the screen.
      */
-    UiObject2 assertShownById(String id) throws Exception {
+    public UiObject2 assertShownById(String id) throws Exception {
         final UiObject2 object = waitForObject(By.res(id));
         assertThat(object).isNotNull();
         return object;
@@ -422,11 +422,11 @@
     /**
      * Asserts the id is shown on the screen, using a resource id from the test package.
      */
-    UiObject2 assertShownByRelativeId(String id) throws Exception {
+    public UiObject2 assertShownByRelativeId(String id) throws Exception {
         return assertShownByRelativeId(id, mDefaultTimeout);
     }
 
-    UiObject2 assertShownByRelativeId(String id, Timeout timeout) throws Exception {
+    public UiObject2 assertShownByRelativeId(String id, Timeout timeout) throws Exception {
         final UiObject2 obj = waitForObject(By.res(mPackageName, id), timeout);
         assertThat(obj).isNotNull();
         return obj;
@@ -438,17 +438,25 @@
      * <p><b>Note:</b> this method should only called AFTER the id was previously shown, otherwise
      * it might pass without really asserting anything.
      */
-    void assertGoneByRelativeId(@NonNull String id, @NonNull Timeout timeout) {
+    public void assertGoneByRelativeId(@NonNull String id, @NonNull Timeout timeout) {
         assertGoneByRelativeId(/* parent = */ null, id, timeout);
     }
 
+    public void assertGoneByRelativeId(int resId, @NonNull Timeout timeout) {
+        assertGoneByRelativeId(/* parent = */ null, getIdName(resId), timeout);
+    }
+
+    private String getIdName(int resId) {
+        return mContext.getResources().getResourceEntryName(resId);
+    }
+
     /**
      * Asserts the id is not shown on the parent anymore, using a resource id from the test package.
      *
      * <p><b>Note:</b> this method should only called AFTER the id was previously shown, otherwise
      * it might pass without really asserting anything.
      */
-    void assertGoneByRelativeId(@Nullable UiObject2 parent, @NonNull String id,
+    public void assertGoneByRelativeId(@Nullable UiObject2 parent, @NonNull String id,
             @NonNull Timeout timeout) {
         final SearchCondition<Boolean> condition = Until.gone(By.res(mPackageName, id));
         final boolean gone = parent != null
@@ -462,6 +470,16 @@
         }
     }
 
+    public UiObject2 assertShownByRelativeId(int resId) throws Exception {
+        return assertShownByRelativeId(getIdName(resId));
+    }
+
+    public void assertNeverShownByRelativeId(@NonNull String description, int resId, long timeout)
+            throws Exception {
+        final BySelector selector = By.res(Helper.MY_PACKAGE, getIdName(resId));
+        assertNeverShown(description, selector, timeout);
+    }
+
     /**
      * Asserts that a {@code selector} is not showing after {@code timeout} milliseconds.
      */
@@ -479,42 +497,42 @@
     /**
      * Gets the text set on a view.
      */
-    String getTextByRelativeId(String id) throws Exception {
+    public String getTextByRelativeId(String id) throws Exception {
         return waitForObject(By.res(mPackageName, id)).getText();
     }
 
     /**
      * Focus in the view with the given resource id.
      */
-    void focusByRelativeId(String id) throws Exception {
+    public void focusByRelativeId(String id) throws Exception {
         waitForObject(By.res(mPackageName, id)).click();
     }
 
     /**
      * Sets a new text on a view.
      */
-    void setTextByRelativeId(String id, String newText) throws Exception {
+    public void setTextByRelativeId(String id, String newText) throws Exception {
         waitForObject(By.res(mPackageName, id)).setText(newText);
     }
 
     /**
      * Asserts the save snackbar is showing and returns it.
      */
-    UiObject2 assertSaveShowing(int type) throws Exception {
+    public UiObject2 assertSaveShowing(int type) throws Exception {
         return assertSaveShowing(SAVE_TIMEOUT, type);
     }
 
     /**
      * Asserts the save snackbar is showing and returns it.
      */
-    UiObject2 assertSaveShowing(Timeout timeout, int type) throws Exception {
+    public UiObject2 assertSaveShowing(Timeout timeout, int type) throws Exception {
         return assertSaveShowing(null, timeout, type);
     }
 
     /**
      * Asserts the save snackbar is showing with the Update message and returns it.
      */
-    UiObject2 assertUpdateShowing(int... types) throws Exception {
+    public UiObject2 assertUpdateShowing(int... types) throws Exception {
         return assertSaveOrUpdateShowing(/* update= */ true, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
                 null, SAVE_TIMEOUT, types);
     }
@@ -522,7 +540,7 @@
     /**
      * Presses the Back button.
      */
-    void pressBack() {
+    public void pressBack() {
         Log.d(TAG, "pressBack()");
         mDevice.pressBack();
     }
@@ -530,7 +548,7 @@
     /**
      * Presses the Home button.
      */
-    void pressHome() {
+    public void pressHome() {
         Log.d(TAG, "pressHome()");
         mDevice.pressHome();
     }
@@ -538,11 +556,11 @@
     /**
      * Asserts the save snackbar is not showing.
      */
-    void assertSaveNotShowing(int type) throws Exception {
+    public void assertSaveNotShowing(int type) throws Exception {
         assertNeverShown("save UI for type " + type, SAVE_UI_SELECTOR, SAVE_NOT_SHOWN_NAPTIME_MS);
     }
 
-    void assertSaveNotShowing() throws Exception {
+    public void assertSaveNotShowing() throws Exception {
         assertNeverShown("save UI", SAVE_UI_SELECTOR, SAVE_NOT_SHOWN_NAPTIME_MS);
     }
 
@@ -570,26 +588,26 @@
         return getString(typeResourceName);
     }
 
-    UiObject2 assertSaveShowing(String description, int... types) throws Exception {
+    public UiObject2 assertSaveShowing(String description, int... types) throws Exception {
         return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
                 description, SAVE_TIMEOUT, types);
     }
 
-    UiObject2 assertSaveShowing(String description, Timeout timeout, int... types)
+    public UiObject2 assertSaveShowing(String description, Timeout timeout, int... types)
             throws Exception {
         return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
                 description, timeout, types);
     }
 
-    UiObject2 assertSaveShowing(int negativeButtonStyle, String description,
+    public UiObject2 assertSaveShowing(int negativeButtonStyle, String description,
             int... types) throws Exception {
         return assertSaveOrUpdateShowing(/* update= */ false, negativeButtonStyle, description,
                 SAVE_TIMEOUT, types);
     }
 
 
-    UiObject2 assertSaveOrUpdateShowing(boolean update, int negativeButtonStyle, String description,
-            Timeout timeout, int... types) throws Exception {
+    public UiObject2 assertSaveOrUpdateShowing(boolean update, int negativeButtonStyle,
+            String description, Timeout timeout, int... types) throws Exception {
         final UiObject2 snackbar = waitForObject(SAVE_UI_SELECTOR, timeout);
 
         final UiObject2 titleView =
@@ -674,7 +692,7 @@
      * @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
      * @param types expected types of save info.
      */
-    void saveForAutofill(boolean yesDoIt, int... types) throws Exception {
+    public void saveForAutofill(boolean yesDoIt, int... types) throws Exception {
         final UiObject2 saveSnackBar = assertSaveShowing(
                 SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL, null, types);
         saveForAutofill(saveSnackBar, yesDoIt);
@@ -691,7 +709,8 @@
      * @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
      * @param types expected types of save info.
      */
-    void saveForAutofill(int negativeButtonStyle, boolean yesDoIt, int... types) throws Exception {
+    public void saveForAutofill(int negativeButtonStyle, boolean yesDoIt, int... types)
+            throws Exception {
         final UiObject2 saveSnackBar = assertSaveShowing(negativeButtonStyle,null, types);
         saveForAutofill(saveSnackBar, yesDoIt);
     }
@@ -703,7 +722,7 @@
      *            {@link #assertSaveShowing(int)}.
      * @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
      */
-    void saveForAutofill(UiObject2 saveSnackBar, boolean yesDoIt) {
+    public void saveForAutofill(UiObject2 saveSnackBar, boolean yesDoIt) {
         final String id = yesDoIt ? "autofill_save_yes" : "autofill_save_no";
 
         final UiObject2 button = saveSnackBar.findObject(By.res("android", id));
@@ -722,7 +741,7 @@
      * @param id resource id of the field.
      * @param expectOverflow whether overflow menu should be shown (when clipboard contains text)
      */
-    UiObject2 getAutofillMenuOption(String id, boolean expectOverflow) throws Exception {
+    public UiObject2 getAutofillMenuOption(String id, boolean expectOverflow) throws Exception {
         final UiObject2 field = waitForObject(By.res(mPackageName, id));
         // TODO: figure out why obj.longClick() doesn't always work
         field.click(3000);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Visitor.java b/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
index a8e0314..26e62e3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
@@ -22,13 +22,12 @@
  * the UI thread. Example:
  * <pre><code>
  * void onUsername(ViewVisitor<EditText> v) {
- *     runOnUiThread(() -> {
- *         v.visit(mUsername);
- *     });
+ *     runOnUiThread(() -> v.visit(mUsername));
  * }
  * </code></pre>
  */
-interface Visitor<T> {
+// TODO: move to common code
+public interface Visitor<T> {
 
     void visit(T view);
 }
\ No newline at end of file
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
new file mode 100644
index 0000000..c7e55fa
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.Helper.allowOverlays;
+import static android.autofillservice.cts.Helper.disallowOverlays;
+import static android.provider.Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS;
+
+import android.autofillservice.cts.AbstractAutoFillActivity;
+import android.autofillservice.cts.AutoFillServiceTestCase;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedReplier;
+import android.autofillservice.cts.common.SettingsHelper;
+import android.autofillservice.cts.common.SettingsStateChangerRule;
+import android.view.autofill.AutofillManager;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+
+// Must be public because of the @ClassRule
+public abstract class AugmentedAutofillAutoActivityLaunchTestCase
+        <A extends AbstractAutoFillActivity> extends AutoFillServiceTestCase.AutoActivityLaunch<A> {
+
+    @ClassRule
+    public static final SettingsStateChangerRule sFeatureEnabler = new SettingsStateChangerRule(
+            sContext, SettingsHelper.NAMESPACE_GLOBAL, AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
+            Integer.toString(AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM));
+
+    protected static AugmentedReplier sAugmentedReplier;
+    protected AugmentedUiBot mAugmentedUiBot;
+
+    @BeforeClass
+    public static void allowAugmentedAutofillWindow() {
+        allowOverlays();
+    }
+
+    @AfterClass
+    public static void disallowAugmentedAutofillWindow() {
+        disallowOverlays();
+    }
+
+    @Before
+    public void setFixtures() {
+        sAugmentedReplier = CtsAugmentedAutofillService.getAugmentedReplier();
+        sAugmentedReplier.reset();
+        mAugmentedUiBot = new AugmentedUiBot(mUiBot);
+        mSafeCleanerRule
+            .run(() -> sAugmentedReplier.assertNoUnhandledFillRequests())
+            .add(() -> { return sAugmentedReplier.getExceptions(); });
+    }
+
+    @After
+    public void resetService() {
+        AugmentedHelper.resetAugmentedService();
+    }
+
+    protected void enableAugmentedService() {
+        AugmentedHelper.setAugmentedService(CtsAugmentedAutofillService.SERVICE_NAME);
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
new file mode 100644
index 0000000..626b835
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+import static android.view.autofill.AutofillManager.MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.Activity;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.content.ComponentName;
+import android.service.autofill.augmented.FillRequest;
+import android.util.Log;
+import android.util.Pair;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * Helper for common funcionalities.
+ */
+public final class AugmentedHelper {
+
+    private static final String TAG = AugmentedHelper.class.getSimpleName();
+
+    @NonNull
+    public static String getActivityName(@Nullable FillRequest request) {
+        if (request == null) return "N/A (null request)";
+
+        final ComponentName componentName = request.getActivityComponent();
+        if (componentName == null) return "N/A (no component name)";
+
+        return componentName.flattenToShortString();
+    }
+
+    /**
+     * Sets the augmented capture service.
+     */
+    public static void setAugmentedService(@NonNull String service) {
+        Log.d(TAG, "Setting service to " + service);
+        runShellCommand("cmd autofill set temporary-augmented-service 0 %s %d", service,
+                MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS);
+    }
+
+    /**
+     * Resets the content capture service.
+     */
+    public static void resetAugmentedService() {
+        Log.d(TAG, "Resetting back to default service");
+        runShellCommand("cmd autofill set temporary-augmented-service 0");
+    }
+
+    public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
+            @NonNull Activity activity, @NonNull AutofillId expectedFocusedId,
+            @NonNull AutofillValue expectedFocusedValue) {
+        Preconditions.checkNotNull(activity);
+        Preconditions.checkNotNull(expectedFocusedId);
+        assertWithMessage("no AugmentedFillRequest").that(request).isNotNull();
+        assertWithMessage("no FillRequest on %s", request).that(request.request).isNotNull();
+        assertWithMessage("no FillController on %s", request).that(request.controller).isNotNull();
+        assertWithMessage("no FillCallback on %s", request).that(request.callback).isNotNull();
+        // TODO(b/122728762): re-add when set
+//        assertWithMessage("no CancellationSignal on %s", request).that(request.cancellationSignal)
+//                .isNotNull();
+        // NOTE: task id can change, we might need to set it in the activity's onCreate()
+        assertWithMessage("wrong task id on %s", request).that(request.request.getTaskId())
+                .isEqualTo(activity.getTaskId());
+
+        final ComponentName actualComponentName = request.request.getActivityComponent();
+        assertWithMessage("no activity name on %s", request).that(actualComponentName).isNotNull();
+        assertWithMessage("wrong activity name on %s", request).that(actualComponentName)
+                .isEqualTo(activity.getComponentName());
+        final AutofillId actualFocusedId = request.request.getFocusedId();
+        assertWithMessage("no focused id on %s", request).that(actualFocusedId).isNotNull();
+        assertWithMessage("wrong focused id on %s", request).that(actualFocusedId)
+                .isEqualTo(expectedFocusedId);
+        final AutofillValue actualFocusedValue = request.request.getFocusedValue();
+        assertWithMessage("no focused value on %s", request).that(actualFocusedValue).isNotNull();
+        assertAutofillValue(expectedFocusedValue, actualFocusedValue);
+    }
+
+    public static void assertAutofillValue(final AutofillValue expectedValue,
+            final AutofillValue actualValue) {
+        // It only supports text values for now...
+        assertWithMessage("expected value is not text: %s", expectedValue)
+                .that(expectedValue.isText()).isTrue();
+        assertWithMessage("actual value is not text: %s", actualValue)
+                .that(actualValue.isText()).isTrue();
+
+        assertWithMessage("wrong autofill value").that(actualValue.getTextValue())
+                .isEqualTo(expectedValue.getTextValue());
+    }
+
+    @NonNull
+    public static String toString(@Nullable List<Pair<AutofillId, AutofillValue>> values) {
+        if (values == null) return "null";
+        final StringBuilder string = new StringBuilder("[");
+        final int size = values.size();
+        for (int i = 0; i < size; i++) {
+            final Pair<AutofillId, AutofillValue> value = values.get(i);
+            string.append(i).append(':').append(value.first).append('=')
+                   .append(Helper.toString(value.second));
+            if (i < size - 1) {
+                string.append(", ");
+            }
+
+        }
+        return string.append(']').toString();
+    }
+
+    @NonNull
+    public static String toString(@Nullable FillRequest request) {
+        if (request == null) return "(null request)";
+
+        final StringBuilder string =
+                new StringBuilder("FillRequest[act=").append(getActivityName(request))
+                .append(", taskId=").append(request.getTaskId());
+
+        final AutofillId focusedId = request.getFocusedId();
+        if (focusedId != null) {
+            string.append(", focusedId=").append(focusedId);
+        }
+        final AutofillValue focusedValue = request.getFocusedValue();
+        if (focusedValue != null) {
+            string.append(", focusedValue=").append(focusedValue);
+        }
+
+        return string.append(']').toString();
+    }
+
+    // Used internally by UiBot to assert the UI
+    static String getContentDescriptionForUi(@NonNull AutofillId focusedId) {
+        return "ui_for_" + focusedId;
+    }
+
+    private AugmentedHelper() {
+        throw new UnsupportedOperationException("contain static methods only");
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
new file mode 100644
index 0000000..cbf2671
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.augmented.AugmentedHelper.assertBasicRequestInfo;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.DO_NOT_REPLY_AUGMENTED_RESPONSE;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.NO_AUGMENTED_RESPONSE;
+
+import android.autofillservice.cts.AutofillActivityTestRule;
+import android.autofillservice.cts.LoginActivity;
+import android.autofillservice.cts.OneTimeCancellationSignalListener;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.support.test.uiautomator.UiObject2;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.EditText;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class AugmentedLoginActivityTest
+        extends AugmentedAutofillAutoActivityLaunchTestCase<LoginActivity> {
+
+    protected LoginActivity mActivity;
+
+    @Override
+    protected AutofillActivityTestRule<LoginActivity> getActivityRule() {
+        return new AutofillActivityTestRule<LoginActivity>(
+                LoginActivity.class) {
+            @Override
+            protected void afterActivityLaunched() {
+                mActivity = getActivity();
+            }
+        };
+    }
+
+    @Test
+    public void testAutoFill_neitherServiceCanAutofill() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText username = mActivity.getUsername();
+        final AutofillValue expectedFocusedValue = username.getAutofillValue();
+        final AutofillId expectedFocusedId = username.getAutofillId();
+        sReplier.addResponse(NO_RESPONSE);
+        sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
+
+        // Trigger autofill
+        mActivity.onUsername(View::requestFocus);
+        sReplier.getNextFillRequest();
+        final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request, mActivity, expectedFocusedId, expectedFocusedValue);
+
+        // Make sure standard Autofill UI is not shown.
+        mUiBot.assertNoDatasetsEver();
+
+        // Make sure Augmented Autofill UI is not shown.
+        mAugmentedUiBot.assertUiNeverShown();
+    }
+
+    @Test
+    public void testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText username = mActivity.getUsername();
+        final AutofillId usernameId = username.getAutofillId();
+        final AutofillValue expectedFocusedValue = username.getAutofillValue();
+        sReplier.addResponse(NO_RESPONSE);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+                        .setField(usernameId, "dude")
+                        .build(), usernameId)
+                .build());
+        mActivity.expectAutoFill("dude");
+
+        // Trigger autofill
+        mActivity.onUsername(View::requestFocus);
+        sReplier.getNextFillRequest();
+        final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
+
+        // Make sure standard Autofill UI is not shown.
+        mUiBot.assertNoDatasetsEver();
+
+        // Make sure Augmented Autofill UI is shown.
+        final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+
+        // Autofill
+        ui.click();
+        mActivity.assertAutoFilled();
+        mAugmentedUiBot.assertUiGone();
+    }
+
+    @Test
+    public void testAutoFill_mainServiceReturnedNull_augmentedAutofillTwoFields() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText username = mActivity.getUsername();
+        final AutofillId usernameId = username.getAutofillId();
+        final AutofillValue expectedFocusedValue = username.getAutofillValue();
+        sReplier.addResponse(NO_RESPONSE);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+                        .setField(usernameId, "dude")
+                        .setField(mActivity.getPassword().getAutofillId(), "sweet")
+                        .build(), usernameId)
+                .build());
+        mActivity.expectAutoFill("dude", "sweet");
+
+        // Trigger autofill
+        mActivity.onUsername(View::requestFocus);
+        sReplier.getNextFillRequest();
+        final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
+
+        // Make sure standard Autofill UI is not shown.
+        mUiBot.assertNoDatasetsEver();
+
+        // Make sure Augmented Autofill UI is shown.
+        final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+
+        // Autofill
+        ui.click();
+        mActivity.assertAutoFilled();
+        mAugmentedUiBot.assertUiGone();
+    }
+
+    @Ignore("blocked on b/122728762")
+    @Test
+    public void testCancellationSignalCalledAfterTimeout() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        sReplier.addResponse(NO_RESPONSE);
+        sAugmentedReplier.addResponse(DO_NOT_REPLY_AUGMENTED_RESPONSE);
+        final OneTimeCancellationSignalListener listener =
+                new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 2000);
+
+        // Trigger autofill
+        mActivity.onUsername(View::requestFocus);
+        sReplier.getNextFillRequest();
+
+        // TODO(b/122728762): might need to wait until connected
+        sAugmentedReplier.getNextFillRequest().cancellationSignal.setOnCancelListener(listener);
+
+        // Assert results
+        listener.assertOnCancelCalled();
+    }
+
+    /*
+     * TODO(b/119638958) - add moarrrr tests:
+     *
+     * - Augmented service returned null
+     * - Focus back and forth between username and passwod
+     *   - When Augmented service shows UI on one field (like username) but not other.
+     *   - When Augmented service shows UI on one field (like username) on both.
+     * - Tap back
+     * - Tap home (then bring activity back)
+     * - Acitivy is killed (and restored)
+     * - Main service returns non-null response that doesn't show UI (for example, has just
+     *   SaveInfo)
+     *   - Augmented autofill show UI, user fills, Save UI is shown
+     *   - etc ...
+     * - No augmented autofill calls when the main service is not set.
+     * - etc...
+     */
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
new file mode 100644
index 0000000..730b0d4
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import android.autofillservice.cts.Timeout;
+
+/**
+ * Timeouts for common tasks.
+ */
+final class AugmentedTimeouts {
+
+    private static final long ONE_TIMEOUT_TO_RULE_THEN_ALL_MS = 1_000;
+    private static final long ONE_NAPTIME_TO_RULE_THEN_ALL_MS = 3_000;
+
+    /**
+     * Timeout for expected augmented autofill requests.
+     */
+    static final Timeout AUGMENTED_FILL_TIMEOUT = new Timeout("AUGMENTED_FILL_TIMEOUT",
+            ONE_TIMEOUT_TO_RULE_THEN_ALL_MS, 2F, ONE_TIMEOUT_TO_RULE_THEN_ALL_MS);
+
+    /**
+     * Timeout until framework binds / unbinds from service.
+     */
+    static final Timeout AUGMENTED_CONNECTION_TIMEOUT = new Timeout("AUGMENTED_CONNECTION_TIMEOUT",
+            ONE_TIMEOUT_TO_RULE_THEN_ALL_MS, 2F, ONE_TIMEOUT_TO_RULE_THEN_ALL_MS);
+
+    /**
+     * Timeout used when the augmented autofill UI not expected to be shown - test will sleep for
+     * that amount of time as there is no callback that be received to assert it's not shown.
+     */
+    static final long AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS = ONE_NAPTIME_TO_RULE_THEN_ALL_MS;
+
+    private AugmentedTimeouts() {
+        throw new UnsupportedOperationException("contain static methods only");
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java
new file mode 100644
index 0000000..ed00223
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getContentDescriptionForUi;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.autofillservice.cts.R;
+import android.autofillservice.cts.UiBot;
+import android.support.test.uiautomator.UiObject2;
+import android.view.autofill.AutofillId;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Helper for UI-related needs.
+ */
+public final class AugmentedUiBot {
+
+    private final UiBot mUiBot;
+    private boolean mOkToCallAssertUiGone;
+
+    public AugmentedUiBot(@NonNull UiBot uiBot) {
+        mUiBot = uiBot;
+    }
+
+    /**
+     * Asserts the augmented autofill UI was never shown.
+     *
+     * <p>This method is slower than {@link #assertUiGone()} and should only be called in the
+     * cases where the dataset picker was not previous shown.
+     */
+    public void assertUiNeverShown() throws Exception {
+        mUiBot.assertNeverShownByRelativeId("augmented autofil UI", R.id.augmentedAutofillUi,
+                AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS);
+    }
+
+    /**
+     * Asserts the augmented autofill UI was shown.
+     *
+     * @param focusedId where it should have been shown
+     * @param expectedText the expected text in the UI
+     */
+    public UiObject2 assertUiShown(@NonNull AutofillId focusedId,
+            @NonNull String expectedText) throws Exception {
+        Preconditions.checkNotNull(focusedId);
+        Preconditions.checkNotNull(expectedText);
+
+        final UiObject2 ui = mUiBot.assertShownByRelativeId(R.id.augmentedAutofillUi);
+
+        assertWithMessage("Wrong text on UI").that(ui.getText()).isEqualTo(expectedText);
+
+        final String expectedContentDescription = getContentDescriptionForUi(focusedId);
+        assertWithMessage("Wrong content description on UI")
+                .that(ui.getContentDescription()).isEqualTo(expectedContentDescription);
+
+        mOkToCallAssertUiGone = true;
+
+        return ui;
+    }
+
+    /**
+     * Asserts the augmented autofill UI is gone AFTER it was previously shown.
+     *
+     * @throws IllegalStateException if this method is called without calling
+     * {@link #assertUiShown(AutofillId, String)} before.
+     */
+    public void assertUiGone() {
+        Preconditions.checkState(mOkToCallAssertUiGone, "must call assertUiShown() first");
+        mUiBot.assertGoneByRelativeId(R.id.augmentedAutofillUi, AUGMENTED_FILL_TIMEOUT);
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
new file mode 100644
index 0000000..8aada3f
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getContentDescriptionForUi;
+
+import android.autofillservice.cts.R;
+import android.content.Context;
+import android.service.autofill.augmented.FillCallback;
+import android.service.autofill.augmented.FillController;
+import android.service.autofill.augmented.FillRequest;
+import android.service.autofill.augmented.FillResponse;
+import android.service.autofill.augmented.FillWindow;
+import android.service.autofill.augmented.PresentationParams;
+import android.service.autofill.augmented.PresentationParams.Area;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Helper class used to produce a {@link FillResponse}.
+ */
+public final class CannedAugmentedFillResponse {
+
+    private static final String TAG = CannedAugmentedFillResponse.class.getSimpleName();
+
+    private final AugmentedResponseType mResponseType;
+    private final Map<AutofillId, Dataset> mDatasets;
+
+    private CannedAugmentedFillResponse(@NonNull Builder builder) {
+        mResponseType = builder.mResponseType;
+        mDatasets = builder.mDatasets;
+    }
+
+    /**
+     * Constant used to pass a {@code null} response to the
+     * {@link FillCallback#onSuccess(FillResponse)} method.
+     */
+    public static final CannedAugmentedFillResponse NO_AUGMENTED_RESPONSE =
+            new Builder(AugmentedResponseType.NULL).build();
+
+    /**
+     * Constant used to emulate a timeout by not calling any method on {@link FillCallback}.
+     */
+    public static final CannedAugmentedFillResponse DO_NOT_REPLY_AUGMENTED_RESPONSE =
+            new Builder(AugmentedResponseType.TIMEOUT).build();
+
+    public AugmentedResponseType getResponseType() {
+        return mResponseType;
+    }
+
+    /**
+     * Creates the "real" response.
+     */
+    public FillResponse asFillResponse(@NonNull Context context, @NonNull FillRequest request,
+            @NonNull FillController controller) {
+        final AutofillId focusedId = request.getFocusedId();
+
+        final Dataset dataset = mDatasets.get(focusedId);
+        if (dataset == null) {
+            Log.d(TAG, "no dataset for field " + focusedId);
+            return null;
+        }
+
+        Log.d(TAG, "asFillResponse: id=" + focusedId + ", dataset=" + dataset);
+
+        final PresentationParams presentationParams = request.getPresentationParams();
+        if (presentationParams == null) {
+            Log.w(TAG, "No PresentationParams");
+            return null;
+        }
+
+        final Area strip = presentationParams.getSuggestionArea();
+        if (strip == null) {
+            Log.w(TAG, "No suggestion strip");
+            return null;
+        }
+
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        final TextView rootView = (TextView) inflater.inflate(R.layout.augmented_autofill_ui, null);
+
+        rootView.setText(dataset.mPresentation);
+
+        rootView.setContentDescription(getContentDescriptionForUi(focusedId));
+        final FillWindow fillWindow = new FillWindow();
+        rootView.setOnClickListener((v) -> {
+            Log.d(TAG, "Destroying window first");
+            fillWindow.destroy();
+            final List<Pair<AutofillId, AutofillValue>> values = dataset.getValues();
+            Log.i(TAG, "Autofilling: " + AugmentedHelper.toString(values));
+            controller.autofill(values);
+        });
+
+        boolean ok = fillWindow.update(strip, rootView, 0);
+        if (!ok) {
+            Log.w(TAG, "FillWindow.update() failed for " + strip + " and " + rootView);
+            return null;
+        }
+
+        return new FillResponse.Builder().setFillWindow(fillWindow).build();
+    }
+
+    @Override
+    public String toString() {
+        return "CannedAugmentedFillResponse: [type=" + mResponseType
+                + ",datasets=" + mDatasets
+                + "]";
+    }
+    public enum AugmentedResponseType {
+        NORMAL,
+        NULL,
+        TIMEOUT,
+    }
+
+    public static final class Builder {
+        private final Map<AutofillId, Dataset> mDatasets = new ArrayMap<>();
+        private final AugmentedResponseType mResponseType;
+
+        public Builder(@NonNull AugmentedResponseType type) {
+            mResponseType = type;
+        }
+
+        public Builder() {
+            this(AugmentedResponseType.NORMAL);
+        }
+
+        /**
+         * Sets the {@link Dataset} that will be filled when the given {@code ids} is focused and
+         * the UI is tapped.
+         */
+        public Builder setDataset(@NonNull Dataset dataset, @NonNull AutofillId... ids) {
+            for (AutofillId id : ids) {
+                mDatasets.put(id, dataset);
+            }
+            return this;
+        }
+
+        public CannedAugmentedFillResponse build() {
+            return new CannedAugmentedFillResponse(this);
+        }
+    } // CannedAugmentedFillResponse.Builder
+
+
+    /**
+     * Helper class used to define which fields will be autofilled when the user taps the Augmented
+     * Autofill UI.
+     */
+    public static class Dataset {
+        private final Map<AutofillId, AutofillValue> mFieldValuesById;
+        private final String mPresentation;
+
+        private Dataset(@NonNull Builder builder) {
+            mFieldValuesById = builder.mFieldValuesById;
+            mPresentation = builder.mPresentation;
+        }
+
+        public List<Pair<AutofillId, AutofillValue>> getValues() {
+            return mFieldValuesById.entrySet().stream()
+                    .map((entry) -> (new Pair<>(entry.getKey(), entry.getValue())))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        public String toString() {
+            return "Dataset: [presentation=" + mPresentation
+                    + ", fields=" + mFieldValuesById
+                    + "]";
+        }
+
+        public static class Builder {
+            private final Map<AutofillId, AutofillValue> mFieldValuesById = new ArrayMap<>();
+
+            private final String mPresentation;
+
+            public Builder(@NonNull String presentation) {
+                mPresentation = Preconditions.checkNotNull(presentation);
+            }
+
+            /**
+             * Sets the value that will be autofilled on the field with {@code id}.
+             */
+            public Builder setField(@NonNull AutofillId id, String text) {
+                mFieldValuesById.put(id, AutofillValue.forText(text));
+                return this;
+            }
+            public Dataset build() {
+                return new Dataset(this);
+            }
+        } // Dataset.Builder
+    } // Dataset
+} // CannedAugmentedFillResponse
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
new file mode 100644
index 0000000..8fb17a2
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2019 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.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getActivityName;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_CONNECTION_TIMEOUT;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.AugmentedResponseType.NULL;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.AugmentedResponseType.TIMEOUT;
+
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.JUnitHelper;
+import android.autofillservice.cts.RetryableException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.service.autofill.augmented.AugmentedAutofillService;
+import android.service.autofill.augmented.FillCallback;
+import android.service.autofill.augmented.FillController;
+import android.service.autofill.augmented.FillRequest;
+import android.service.autofill.augmented.FillResponse;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementation of {@link AugmentedAutofillService} used in the tests.
+ */
+public class CtsAugmentedAutofillService extends AugmentedAutofillService {
+
+    private static final String TAG = CtsAugmentedAutofillService.class.getSimpleName();
+
+    public static final String SERVICE_PACKAGE = Helper.MY_PACKAGE;
+    public static final String SERVICE_CLASS = CtsAugmentedAutofillService.class.getSimpleName();
+
+    public static final String SERVICE_NAME = SERVICE_PACKAGE + "/.augmented." + SERVICE_CLASS;
+
+    private static final AugmentedReplier sAugmentedReplier = new AugmentedReplier();
+
+    // We must handle all requests in a separate thread as the service's main thread is the also
+    // the UI thread of the test process and we don't want to hose it in case of failures here
+    private static final HandlerThread sMyThread = new HandlerThread("MyAugmentedServiceThread");
+    private final Handler mHandler;
+
+    static {
+        Log.i(TAG, "Starting thread " + sMyThread);
+        sMyThread.start();
+    }
+
+    public CtsAugmentedAutofillService() {
+        mHandler = Handler.createAsync(sMyThread.getLooper());
+    }
+
+    @Override
+    public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+            FillController controller, FillCallback callback) {
+        Log.i(TAG, "onFillRequest(): " + AugmentedHelper.toString(request));
+
+        final ComponentName component = request.getActivityComponent();
+
+        if (!JUnitHelper.isRunningTest()) {
+            Log.e(TAG, "onFillRequest(" + component + ") called after tests finished");
+            return;
+        }
+        mHandler.post(() -> sAugmentedReplier.handleOnFillRequest(getApplicationContext(), request,
+                cancellationSignal, controller, callback));
+    }
+
+    /**
+     * Gets the {@link AugmentedReplier} singleton.
+     */
+    static AugmentedReplier getAugmentedReplier() {
+        return sAugmentedReplier;
+    }
+
+    /**
+     * POJO representation of the contents of a {@link FillRequest}
+     * that can be asserted at the end of a test case.
+     */
+    public static final class AugmentedFillRequest {
+        public final FillRequest request;
+        public final CancellationSignal cancellationSignal;
+        public final FillController controller;
+        public final FillCallback callback;
+
+        private AugmentedFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+                FillController controller, FillCallback callback) {
+            this.request = request;
+            this.cancellationSignal = cancellationSignal;
+            this.controller = controller;
+            this.callback = callback;
+        }
+
+        @Override
+        public String toString() {
+            return "AugmentedFillRequest[activity=" + getActivityName(request) + ", request="
+                    + AugmentedHelper.toString(request) + "]";
+        }
+    }
+
+    /**
+     * Object used to answer a
+     * {@link AugmentedAutofillService#onFillRequest(FillRequest, CancellationSignal,
+     * FillController, FillCallback)} on behalf of a unit test method.
+     */
+    public static final class AugmentedReplier {
+
+        private final BlockingQueue<CannedAugmentedFillResponse> mResponses =
+                new LinkedBlockingQueue<>();
+        private final BlockingQueue<AugmentedFillRequest> mFillRequests =
+                new LinkedBlockingQueue<>();
+
+        private List<Throwable> mExceptions;
+        private boolean mReportUnhandledFillRequest = true;
+
+        private AugmentedReplier() {
+        }
+
+        /**
+         * Gets the exceptions thrown asynchronously, if any.
+         */
+        @Nullable
+        public List<Throwable> getExceptions() {
+            return mExceptions;
+        }
+
+        private void addException(@Nullable Throwable e) {
+            if (e == null) return;
+
+            if (mExceptions == null) {
+                mExceptions = new ArrayList<>();
+            }
+            mExceptions.add(e);
+        }
+
+        /**
+         * Sets the expectation for the next {@code onFillRequest}.
+         */
+        public AugmentedReplier addResponse(@NonNull CannedAugmentedFillResponse response) {
+            if (response == null) {
+                throw new IllegalArgumentException("Cannot be null - use NO_RESPONSE instead");
+            }
+            mResponses.add(response);
+            return this;
+        }
+        /**
+         * Gets the next fill request, in the order received.
+         */
+        public AugmentedFillRequest getNextFillRequest() {
+            AugmentedFillRequest request;
+            try {
+                request = mFillRequests.poll(AUGMENTED_FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                throw new IllegalStateException("Interrupted", e);
+            }
+            if (request == null) {
+                throw new RetryableException(AUGMENTED_FILL_TIMEOUT, "onFillRequest() not called");
+            }
+            return request;
+        }
+
+        /**
+         * Asserts all {@link AugmentedAutofillService#onFillRequest(FillRequest,
+         * CancellationSignal, FillController, FillCallback)} received by the service were properly
+         * {@link #getNextFillRequest() handled} by the test case.
+         */
+        public void assertNoUnhandledFillRequests() {
+            if (mFillRequests.isEmpty()) return; // Good job, test case!
+
+            if (!mReportUnhandledFillRequest) {
+                // Just log, so it's not thrown again on @After if already thrown on main body
+                Log.d(TAG, "assertNoUnhandledFillRequests(): already reported, "
+                        + "but logging just in case: " + mFillRequests);
+                return;
+            }
+
+            mReportUnhandledFillRequest = false;
+            throw new AssertionError(mFillRequests.size() + " unhandled fill requests: "
+                    + mFillRequests);
+        }
+
+        /**
+         * Gets the current number of unhandled requests.
+         */
+        public int getNumberUnhandledFillRequests() {
+            return mFillRequests.size();
+        }
+
+        /**
+         * Resets its internal state.
+         */
+        public void reset() {
+            mResponses.clear();
+            mFillRequests.clear();
+            mExceptions = null;
+            mReportUnhandledFillRequest = true;
+        }
+
+        private void handleOnFillRequest(@NonNull Context context, @NonNull FillRequest request,
+                @NonNull CancellationSignal cancellationSignal, @NonNull FillController controller,
+                @NonNull FillCallback callback) {
+            try {
+                final CannedAugmentedFillResponse response;
+                try {
+                    response = mResponses.poll(AUGMENTED_CONNECTION_TIMEOUT.ms(),
+                            TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    Log.w(TAG, "Interrupted getting CannedAugmentedFillResponse: " + e);
+                    Thread.currentThread().interrupt();
+                    addException(e);
+                    return;
+                }
+                if (response == null) {
+                    Log.w(TAG, "onFillRequest() for " + getActivityName(request)
+                            + " received when no canned response was set.");
+                    return;
+                }
+                if (response.getResponseType() == NULL) {
+                    Log.d(TAG, "onFillRequest(): replying with null");
+                    callback.onSuccess(null);
+                    return;
+                }
+
+                if (response.getResponseType() == TIMEOUT) {
+                    Log.d(TAG, "onFillRequest(): not replying at all");
+                    return;
+                }
+
+                Log.v(TAG, "onFillRequest(): response = " + response);
+                final FillResponse fillResponse = response.asFillResponse(context, request,
+                        controller);
+                Log.v(TAG, "onFillRequest(): fillResponse = " + fillResponse);
+                callback.onSuccess(fillResponse);
+            } catch (Throwable t) {
+                addException(t);
+            } finally {
+                final AugmentedFillRequest myRequest = new AugmentedFillRequest(request,
+                        cancellationSignal, controller, callback);
+                Log.d(TAG, "offering " + myRequest);
+                Helper.offer(mFillRequests, myRequest, AUGMENTED_CONNECTION_TIMEOUT.ms());
+            }
+        }
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java b/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
index 2a97aee..117c755 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
@@ -16,6 +16,8 @@
 
 package android.autofillservice.cts.common;
 
+import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+
 import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
 import android.util.Log;
@@ -75,4 +77,12 @@
     public static void sendKeyEvent(String keyCode) {
         runShellCommand("input keyevent " + keyCode);
     }
+
+    /**
+     * Allows an app to draw overlaid windows.
+     */
+    public static void setOverlayPermissions(@NonNull String packageName, boolean allowed) {
+        final String action = allowed ? "allow" : "ignore";
+        runShellCommand("appops set %s SYSTEM_ALERT_WINDOW %s", packageName, action);
+    }
 }
diff --git a/tests/camera/libctscamera2jni/Android.mk b/tests/camera/libctscamera2jni/Android.mk
index 7d71676..2cd4f64 100644
--- a/tests/camera/libctscamera2jni/Android.mk
+++ b/tests/camera/libctscamera2jni/Android.mk
@@ -47,7 +47,4 @@
 LOCAL_SDK_VERSION := current
 LOCAL_NDK_STL_VARIANT := c++_shared
 
-# Remove when libjpeg_static_ndk is XOM compatible.
-LOCAL_XOM := false
-
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 0b9f9c3..ab65015 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -555,6 +555,12 @@
         // Only present in reprocessing capture result.
         waiverKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
 
+        // LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID not required if key is not supported.
+        if (!staticInfo.isLogicalMultiCamera() ||
+                !staticInfo.isActivePhysicalCameraIdSupported()) {
+            waiverKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+        }
+
         //Keys not required if RAW is not supported
         if (!staticInfo.isCapabilitySupported(
                 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
@@ -968,6 +974,7 @@
         resultKeys.add(CaptureResult.TONEMAP_PRESET_CURVE);
         resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
         resultKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+        resultKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
         resultKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
 
         return resultKeys;
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 42f2f58..e433ad8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -1968,6 +1968,19 @@
                             "timestamp source", timestampSource, timestampSourcePhysical);
                 }
             }
+
+            // Verify that if multiple focal lengths or apertures are supported, they are in
+            // ascending order.
+            float[] focalLengths = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
+            for (int i = 0; i < focalLengths.length-1; i++) {
+                mCollector.expectTrue("Camera's available focal lengths must be ascending!",
+                        focalLengths[i] < focalLengths[i+1]);
+            }
+            float[] apertures = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
+            for (int i = 0; i < apertures.length-1; i++) {
+                mCollector.expectTrue("Camera's available apertures must be ascending!",
+                        apertures[i] < apertures[i+1]);
+            }
             counter++;
         }
     }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index 6b95f8c..51a1f9b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -309,6 +309,29 @@
     }
 
     /**
+     * Test two image stream (YUV420_888 and JPEG) capture by using ImageReader with the ImageReader
+     * factory method that has usage flag argument.
+     *
+     * <p>Both stream formats are mandatory for Camera2 API</p>
+     */
+    public void testYuvAndJpegWithUsageFlag() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "YUV and JPEG testing for camera " + id);
+                if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                openDevice(id);
+                bufferFormatWithYuvTestByCamera(ImageFormat.JPEG, true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
      * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader.
      *
      */
@@ -330,6 +353,28 @@
     }
 
     /**
+     * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader with the
+     * ImageReader factory method that has usage flag argument.
+     *
+     */
+    public void testImageReaderYuvAndRawWithUsageFlag() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "YUV and RAW testing for camera " + id);
+                if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                openDevice(id);
+                bufferFormatWithYuvTestByCamera(ImageFormat.RAW_SENSOR, true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
      * Check that the center patches for YUV and JPEG outputs for the same frame match for each YUV
      * resolution and format supported.
      */
@@ -685,6 +730,20 @@
      * @param format The capture format to be tested along with yuv format.
      */
     private void bufferFormatWithYuvTestByCamera(int format) throws Exception {
+        bufferFormatWithYuvTestByCamera(format, false);
+    }
+
+    /**
+     * Test capture a given format stream with yuv stream simultaneously.
+     *
+     * <p>Use fixed yuv size, varies targeted format capture size. Single capture is tested.</p>
+     *
+     * @param format The capture format to be tested along with yuv format.
+     * @param setUsageFlag The ImageReader factory method to be used (with or without specifying
+     *                     usage flag)
+     */
+    private void bufferFormatWithYuvTestByCamera(int format, boolean setUsageFlag)
+            throws Exception {
         if (format != ImageFormat.JPEG && format != ImageFormat.RAW_SENSOR
                 && format != ImageFormat.YUV_420_888) {
             throw new IllegalArgumentException("Unsupported format: " + format);
@@ -706,14 +765,25 @@
             try {
                 // Create YUV image reader
                 SimpleImageReaderListener yuvListener  = new SimpleImageReaderListener();
-                yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                        yuvListener);
+                if (setUsageFlag) {
+                    yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                            HardwareBuffer.USAGE_CPU_READ_OFTEN, yuvListener);
+                } else {
+                    yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                            yuvListener);
+                }
+
                 Surface yuvSurface = yuvReader.getSurface();
 
                 // Create capture image reader
                 SimpleImageReaderListener captureListener = new SimpleImageReaderListener();
-                captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
-                        captureListener);
+                if (setUsageFlag) {
+                    captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+                            HardwareBuffer.USAGE_CPU_READ_OFTEN, captureListener);
+                } else {
+                    captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+                            captureListener);
+                }
                 Surface captureSurface = captureReader.getSurface();
 
                 // Capture images.
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
index 6216f36..38f8816 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
@@ -24,6 +24,7 @@
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
+import android.hardware.HardwareBuffer;
 import android.media.Image;
 import android.media.Image.Plane;
 import android.media.ImageReader;
@@ -70,7 +71,6 @@
     }
 
     /**
-     * `
      * <p>
      * Basic YUV420_888 format ImageWriter ImageReader test that checks the
      * images produced by camera can be passed correctly by ImageWriter.
@@ -97,7 +97,29 @@
                     continue;
                 }
                 openDevice(id);
-                readerWriterFormatTestByCamera(ImageFormat.YUV_420_888);
+                readerWriterFormatTestByCamera(ImageFormat.YUV_420_888, false);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Similar to testYuvImageWriterReaderOperation, but use the alternative
+     * factory method of ImageReader and ImageWriter.
+     * </p>
+     */
+    public void testYuvImageWriterReaderOperationAlt() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                openDevice(id);
+                readerWriterFormatTestByCamera(ImageFormat.YUV_420_888, true);
             } finally {
                 closeDevice(id);
             }
@@ -148,7 +170,8 @@
         }
     }
 
-    private void readerWriterFormatTestByCamera(int format)  throws Exception {
+    private void readerWriterFormatTestByCamera(int format, boolean altFactoryMethod)
+            throws Exception {
         List<Size> sizes = getSortedSizesForFormat(mCamera.getId(), mCameraManager, format, null);
         Size maxSize = sizes.get(0);
         if (VERBOSE) {
@@ -157,14 +180,28 @@
 
         // Create ImageReader for camera output.
         SimpleImageReaderListener listenerForCamera  = new SimpleImageReaderListener();
-        createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForCamera);
+        if (altFactoryMethod) {
+            createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES,
+                    HardwareBuffer.USAGE_CPU_READ_OFTEN, listenerForCamera);
+        } else {
+            createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForCamera);
+        }
+
         if (VERBOSE) {
             Log.v(TAG, "Created camera output ImageReader");
         }
 
         // Create ImageReader for ImageWriter output
         SimpleImageReaderListener listenerForWriter  = new SimpleImageReaderListener();
-        mReaderForWriter = createImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForWriter);
+        if (altFactoryMethod) {
+            mReaderForWriter = createImageReader(
+                    maxSize, format, MAX_NUM_IMAGES,
+                    HardwareBuffer.USAGE_CPU_READ_OFTEN, listenerForWriter);
+        } else {
+            mReaderForWriter = createImageReader(
+                    maxSize, format, MAX_NUM_IMAGES, listenerForWriter);
+        }
+
         if (VERBOSE) {
             Log.v(TAG, "Created ImageWriter output ImageReader");
         }
@@ -172,7 +209,11 @@
         // Create ImageWriter
         Surface surface = mReaderForWriter.getSurface();
         assertNotNull("Surface from ImageReader shouldn't be null", surface);
-        mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
+        if (altFactoryMethod) {
+            mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES, format);
+        } else {
+            mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
+        }
         SimpleImageWriterListener writerImageListener = new SimpleImageWriterListener(mWriter);
         mWriter.setOnImageReleasedListener(writerImageListener, mHandler);
 
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index b608f93..ecd5798 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -20,6 +20,8 @@
 
 import android.content.Context;
 import android.graphics.ImageFormat;
+import android.graphics.PointF;
+import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.hardware.camera2.CameraCaptureSession;
 import android.hardware.camera2.CameraCharacteristics;
@@ -66,7 +68,7 @@
  * Tests exercising logical camera setup, configuration, and usage.
  */
 public final class LogicalCameraDeviceTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "LogicalCameraTest";
+    private static final String TAG = "LogicalCameraDeviceTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final int CONFIGURE_TIMEOUT = 5000; //ms
@@ -508,6 +510,237 @@
     }
 
     /**
+     * Test for physical camera switch based on focal length (optical zoom) and crop region
+     * (digital zoom).
+     *
+     * - Focal length and crop region change must be synchronized to not have sudden jump in field
+     *   of view.
+     * - Main physical id must be valid.
+     */
+    @Test
+    public void testLogicalCameraZoomSwitch() throws Exception {
+
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+
+                StaticMetadata staticInfo = mAllStaticInfo.get(id);
+                if (!staticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                if (!staticInfo.isLogicalMultiCamera()) {
+                    Log.i(TAG, "Camera " + id + " is not a logical multi-camera, skipping");
+                    continue;
+                }
+
+                openDevice(id);
+                Size yuvSize = mOrderedPreviewSizes.get(0);
+                // Create a YUV image reader.
+                ImageReader imageReader = CameraTestUtils.makeImageReader(yuvSize,
+                        ImageFormat.YUV_420_888, MAX_IMAGE_COUNT,
+                        new ImageDropperListener(), mHandler);
+
+                List<OutputConfiguration> outputConfigs = new ArrayList<>();
+                OutputConfiguration config = new OutputConfiguration(imageReader.getSurface());
+                outputConfigs.add(config);
+
+                mSessionListener = new BlockingSessionCallback();
+                mSession = configureCameraSessionWithConfig(mCamera, outputConfigs,
+                        mSessionListener, mHandler);
+
+                final float FOV_MARGIN = 0.01f;
+                final float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
+                final int zoomSteps = focalLengths.length;
+                final float maxZoom = staticInfo.getAvailableMaxDigitalZoomChecked();
+                final Rect activeArraySize = staticInfo.getActiveArraySizeChecked();
+                final Set<String> physicalIds =
+                        staticInfo.getCharacteristics().getPhysicalCameraIds();
+
+                CaptureRequest.Builder requestBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                requestBuilder.addTarget(imageReader.getSurface());
+
+                // For each adjacent focal lengths, set different crop region such that the
+                // resulting angle of view is the same. This is to make sure that no sudden FOV
+                // (field of view) jump when switching between different focal lengths.
+                for (int i = 0; i < zoomSteps-1; i++) {
+                    // Start with larger focal length + full active array crop region.
+                    requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i+1]);
+                    requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, activeArraySize);
+                    SimpleCaptureCallback simpleResultListener = new SimpleCaptureCallback();
+                    mSession.setRepeatingRequest(requestBuilder.build(), simpleResultListener,
+                            mHandler);
+                    waitForAeStable(simpleResultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+                    // This is an approximate, assuming that subject distance >> focal length.
+                    float zoomFactor = focalLengths[i+1]/focalLengths[i];
+                    PointF zoomCenter = new PointF(0.5f, 0.5f);
+                    Rect requestCropRegion = getCropRegionForZoom(zoomFactor,
+                            zoomCenter, maxZoom, activeArraySize);
+                    if (VERBOSE) {
+                        Log.v(TAG, "Switching from crop region " + activeArraySize + ", focal " +
+                            "length " + focalLengths[i+1] + " to crop region " + requestCropRegion +
+                            ", focal length " + focalLengths[i]);
+                    }
+
+                    // Create a burst capture to switch between different focal_length/crop_region
+                    // combination with same field of view.
+                    List<CaptureRequest> requests = new ArrayList<CaptureRequest>();
+                    SimpleCaptureCallback listener = new SimpleCaptureCallback();
+
+                    requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i]);
+                    requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, requestCropRegion);
+                    requests.add(requestBuilder.build());
+                    requests.add(requestBuilder.build());
+
+                    requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i+1]);
+                    requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, activeArraySize);
+                    requests.add(requestBuilder.build());
+                    requests.add(requestBuilder.build());
+
+                    requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i]);
+                    requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, requestCropRegion);
+                    requests.add(requestBuilder.build());
+                    requests.add(requestBuilder.build());
+
+                    mSession.captureBurst(requests, listener, mHandler);
+                    TotalCaptureResult[] results = listener.getTotalCaptureResultsForRequests(
+                            requests, WAIT_FOR_RESULT_TIMEOUT_MS);
+
+                    // Verify result metadata to produce similar field of view.
+                    float fov = activeArraySize.width()/(2*focalLengths[i+1]);
+                    for (int j = 0; j < results.length; j++) {
+                        TotalCaptureResult result = results[j];
+                        Float resultFocalLength = result.get(CaptureResult.LENS_FOCAL_LENGTH);
+                        Rect resultCropRegion = result.get(CaptureResult.SCALER_CROP_REGION);
+
+                        if (VERBOSE) {
+                            Log.v(TAG, "Result crop region " + resultCropRegion + ", focal length "
+                                    + resultFocalLength + " for result " + j);
+                        }
+                        float newFov = resultCropRegion.width()/(2*resultFocalLength);
+
+                        mCollector.expectTrue("Field of view must be consistent with focal " +
+                                "length and crop region change cancelling out each other.",
+                                Math.abs(newFov - fov)/fov < FOV_MARGIN);
+
+                        if (staticInfo.isActivePhysicalCameraIdSupported()) {
+                            String activePhysicalId = result.get(
+                                    CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+                            assertTrue(physicalIds.contains(activePhysicalId));
+
+                            StaticMetadata physicalCameraStaticInfo =
+                                    mAllStaticInfo.get(activePhysicalId);
+                            float[] physicalCameraFocalLengths =
+                                    physicalCameraStaticInfo.getAvailableFocalLengthsChecked();
+                            mCollector.expectTrue("Current focal length " + resultFocalLength
+                                    + " must be supported by active physical camera "
+                                    + activePhysicalId, Arrays.asList(CameraTestUtils.toObject(
+                                    physicalCameraFocalLengths)).contains(resultFocalLength));
+                        }
+                    }
+                }
+
+                if (mSession != null) {
+                    mSession.close();
+                }
+
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test that for logical multi-camera, the activePhysicalId is valid, and is the same
+     * for all capture templates.
+     */
+    @Test
+    public void testActivePhysicalId() throws Exception {
+        int[] sTemplates = new int[] {
+            CameraDevice.TEMPLATE_PREVIEW,
+            CameraDevice.TEMPLATE_RECORD,
+            CameraDevice.TEMPLATE_STILL_CAPTURE,
+            CameraDevice.TEMPLATE_VIDEO_SNAPSHOT,
+            CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG,
+            CameraDevice.TEMPLATE_MANUAL,
+        };
+
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+
+                StaticMetadata staticInfo = mAllStaticInfo.get(id);
+                if (!staticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                if (!staticInfo.isLogicalMultiCamera()) {
+                    Log.i(TAG, "Camera " + id + " is not a logical multi-camera, skipping");
+                    continue;
+                }
+
+                if (!staticInfo.isActivePhysicalCameraIdSupported()) {
+                    continue;
+                }
+
+                final Set<String> physicalIds =
+                        staticInfo.getCharacteristics().getPhysicalCameraIds();
+                openDevice(id);
+                Size previewSz =
+                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
+                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+
+                String storedActiveId = null;
+                for (int template : sTemplates) {
+                    try {
+                        CaptureRequest.Builder requestBuilder =
+                                mCamera.createCaptureRequest(template);
+                        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                        startPreview(requestBuilder, previewSz, listener);
+                        waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+                        CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+                        String activePhysicalId = result.get(
+                                CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+
+                        assertNotNull("activePhysicalId must not be null", activePhysicalId);
+                        if (storedActiveId == null) {
+                            storedActiveId = activePhysicalId;
+                            assertTrue(
+                                  "Camera device reported invalid activePhysicalId: " +
+                                  activePhysicalId, physicalIds.contains(activePhysicalId));
+                        } else {
+                            assertTrue(
+                                  "Camera device reported different activePhysicalId " +
+                                  activePhysicalId + " vs " + storedActiveId +
+                                  " for different capture templates",
+                                  storedActiveId.equals(activePhysicalId));
+                        }
+                    } catch (IllegalArgumentException e) {
+                        if (template == CameraDevice.TEMPLATE_MANUAL &&
+                                !staticInfo.isCapabilitySupported(CameraCharacteristics.
+                                REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                            // OK
+                        } else if (template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG &&
+                                !staticInfo.isCapabilitySupported(CameraCharacteristics.
+                                REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING)) {
+                            // OK.
+                        } else {
+                            throw e; // rethrow
+                        }
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
      * Find a common preview size that's supported by both the logical camera and
      * two of the underlying physical cameras.
      */
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index e98229d..35507e9 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -26,6 +26,7 @@
 import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.params.SessionConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.HardwareBuffer;
 import android.util.Size;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.media.CamcorderProfile;
@@ -35,6 +36,7 @@
 import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.media.Image;
 import android.media.ImageReader;
+import android.media.ImageWriter;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -104,6 +106,11 @@
     private Size mVideoSize;
     private long mRecordingStartTime;
 
+    private Surface mIntermediateSurface;
+    private ImageReader mIntermediateReader;
+    private ImageWriter mIntermediateWriter;
+    private ImageWriterQueuer mQueuer;
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
@@ -115,6 +122,11 @@
     }
 
     private void doBasicRecording(boolean useVideoStab) throws Exception {
+        doBasicRecording(useVideoStab, false);
+    }
+
+    private void doBasicRecording(boolean useVideoStab, boolean useIntermediateSurface)
+            throws Exception {
         for (int i = 0; i < mCameraIds.length; i++) {
             try {
                 Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
@@ -144,7 +156,8 @@
                 openDevice(mCameraIds[i]);
                 initSupportedVideoSize(mCameraIds[i]);
 
-                basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab);
+                basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab,
+                        useIntermediateSurface);
             } finally {
                 closeDevice();
                 releaseRecorder();
@@ -165,7 +178,7 @@
      * recorded video. Preview is set to the video size.
      * </p>
      */
-    @Test
+    @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
     public void testBasicVideoStabilizationRecording() throws Exception {
         doBasicRecording(/*useVideoStab*/true);
     }
@@ -189,6 +202,21 @@
 
     /**
      * <p>
+     * Test camera recording with intermediate surface.
+     * </p>
+     * <p>
+     * This test is similar to testBasicRecording with a tweak where an intermediate
+     * surface is setup between camera and MediaRecorder, giving application a chance
+     * to decide whether to send a frame to recorder or not.
+     * </p>
+     */
+    @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
+    public void testIntermediateSurfaceRecording() throws Exception {
+        doBasicRecording(/*useVideoStab*/false, /*useIntermediateSurface*/true);
+    }
+
+    /**
+     * <p>
      * Test basic camera recording from a persistent input surface.
      * </p>
      * <p>
@@ -926,12 +954,17 @@
 
     }
 
+    private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab)
+            throws Exception {
+        basicRecordingTestByCamera(camcorderProfileList, useVideoStab, false);
+    }
+
     /**
      * Test camera recording by using each available CamcorderProfile for a
      * given camera. preview size is set to the video size.
      */
-    private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab)
-            throws Exception {
+    private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab,
+            boolean useIntermediateSurface) throws Exception {
         Size maxPreviewSize = mOrderedPreviewSizes.get(0);
         List<Range<Integer> > fpsRanges = Arrays.asList(
                 mStaticInfo.getAeAvailableTargetFpsRangesChecked());
@@ -977,20 +1010,21 @@
                         + videoSz.toString() + ".mp4";
             }
 
-            prepareRecordingWithProfile(profile);
+            prepareRecordingWithProfile(profile, useIntermediateSurface);
 
             // prepare preview surface by using video size.
             updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
 
             // Start recording
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-            startRecording(/* useMediaRecorder */true, resultListener, useVideoStab);
+            startRecording(/* useMediaRecorder */true, resultListener, useVideoStab,
+                    useIntermediateSurface);
 
             // Record certain duration.
             SystemClock.sleep(RECORDING_DURATION_MS);
 
             // Stop recording and preview
-            stopRecording(/* useMediaRecorder */true);
+            stopRecording(/* useMediaRecorder */true, useIntermediateSurface);
             // Convert number of frames camera produced into the duration in unit of ms.
             float frameDurationMs = 1000.0f / profile.videoFrameRate;
             float durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
@@ -1060,7 +1094,7 @@
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
             startRecording(
                     /* useMediaRecorder */true, resultListener,
-                    /*useVideoStab*/false, fpsRange);
+                    /*useVideoStab*/false, fpsRange, false);
 
             // Record certain duration.
             SystemClock.sleep(RECORDING_DURATION_MS);
@@ -1462,12 +1496,16 @@
         updatePreviewSurface(previewSize);
     }
 
+    private void prepareRecordingWithProfile(CamcorderProfile profile) throws Exception {
+        prepareRecordingWithProfile(profile, false);
+    }
+
     /**
      * Configure MediaRecorder recording session with CamcorderProfile, prepare
      * the recording surface.
      */
-    private void prepareRecordingWithProfile(CamcorderProfile profile)
-            throws Exception {
+    private void prepareRecordingWithProfile(CamcorderProfile profile,
+            boolean useIntermediateSurface) throws Exception {
         // Prepare MediaRecorder.
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
         mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
@@ -1484,6 +1522,19 @@
         assertNotNull("Recording surface must be non-null!", mRecordingSurface);
         mVideoFrameRate = profile.videoFrameRate;
         mVideoSize = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+
+        if (useIntermediateSurface) {
+            mIntermediateReader = ImageReader.newInstance(
+                    profile.videoFrameWidth, profile.videoFrameHeight,
+                    ImageFormat.PRIVATE, /*maxImages*/3, HardwareBuffer.USAGE_VIDEO_ENCODE);
+
+            mIntermediateSurface = mIntermediateReader.getSurface();
+            mIntermediateWriter = ImageWriter.newInstance(mRecordingSurface, /*maxImages*/3,
+                    ImageFormat.PRIVATE);
+            mQueuer = new ImageWriterQueuer(mIntermediateWriter);
+
+            mIntermediateReader.setOnImageAvailableListener(mQueuer, mHandler);
+        }
     }
 
     /**
@@ -1519,12 +1570,20 @@
 
     private void startRecording(boolean useMediaRecorder,
             CameraCaptureSession.CaptureCallback listener, boolean useVideoStab) throws Exception {
-        startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null);
+        startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null,
+                /*useIntermediateSurface*/false);
     }
 
     private void startRecording(boolean useMediaRecorder,
             CameraCaptureSession.CaptureCallback listener, boolean useVideoStab,
-            Range<Integer> variableFpsRange) throws Exception {
+            boolean useIntermediateSurface) throws Exception {
+        startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null,
+                useIntermediateSurface);
+    }
+
+    private void startRecording(boolean useMediaRecorder,
+            CameraCaptureSession.CaptureCallback listener, boolean useVideoStab,
+            Range<Integer> variableFpsRange, boolean useIntermediateSurface) throws Exception {
         if (!mStaticInfo.isVideoStabilizationSupported() && useVideoStab) {
             throw new IllegalArgumentException("Video stabilization is not supported");
         }
@@ -1533,7 +1592,12 @@
         assertTrue("Both preview and recording surfaces should be valid",
                 mPreviewSurface.isValid() && mRecordingSurface.isValid());
         outputSurfaces.add(mPreviewSurface);
-        outputSurfaces.add(mRecordingSurface);
+        if (useIntermediateSurface) {
+            outputSurfaces.add(mIntermediateSurface);
+        } else {
+            outputSurfaces.add(mRecordingSurface);
+        }
+
         // Video snapshot surface
         if (mReaderSurface != null) {
             outputSurfaces.add(mReaderSurface);
@@ -1551,7 +1615,11 @@
             recordingRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,
                     CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON);
         }
-        recordingRequestBuilder.addTarget(mRecordingSurface);
+        if (useIntermediateSurface) {
+            recordingRequestBuilder.addTarget(mIntermediateSurface);
+        } else {
+            recordingRequestBuilder.addTarget(mRecordingSurface);
+        }
         recordingRequestBuilder.addTarget(mPreviewSurface);
         CaptureRequest recordingRequest = recordingRequestBuilder.build();
         mSession = configureCameraSessionWithParameters(mCamera, outputSurfaces, mSessionListener,
@@ -1631,8 +1699,13 @@
         mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
     }
 
-    // Stop recording and return the estimated video duration in milliseconds.
     private int stopRecording(boolean useMediaRecorder) throws Exception {
+        return stopRecording(useMediaRecorder, false);
+    }
+
+    // Stop recording and return the estimated video duration in milliseconds.
+    private int stopRecording(boolean useMediaRecorder, boolean useIntermediateSurface)
+            throws Exception {
         long stopRecordingTime = SystemClock.elapsedRealtime();
         if (useMediaRecorder) {
             stopCameraStreaming();
@@ -1647,6 +1720,16 @@
             mRecordingSurface.release();
             mRecordingSurface = null;
         }
+        if (useIntermediateSurface) {
+            mIntermediateSurface.release();
+            mIntermediateReader.close();
+            mIntermediateWriter.close();
+            mQueuer.close();
+            mIntermediateSurface = null;
+            mIntermediateReader = null;
+            mIntermediateWriter = null;
+            mQueuer = null;
+        }
         return (int) (stopRecordingTime - mRecordingStartTime);
     }
 
@@ -1955,4 +2038,28 @@
         MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         return mcl.findEncoderForFormat(format) != null;
     }
+
+    private static class ImageWriterQueuer implements ImageReader.OnImageAvailableListener {
+        public ImageWriterQueuer(ImageWriter writer) {
+            mWriter = writer;
+        }
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            Image image = null;
+            try {
+                image = reader.acquireNextImage();
+            } finally {
+                if (image != null && mWriter != null) {
+                    mWriter.queueInputImage(image);
+                }
+            }
+        }
+
+        public void close() {
+            mWriter = null;
+        }
+
+        private ImageWriter mWriter = null;
+    }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
index 1169e64..7fd1e2b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -331,6 +331,31 @@
     }
 
     /**
+     * Create an {@link ImageReader} object and get the surface.
+     * <p>
+     * This function creates {@link ImageReader} object and surface, then assign
+     * to the default {@link mReader} and {@link mReaderSurface}. It closes the
+     * current default active {@link ImageReader} if it exists.
+     * </p>
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired
+     *            simultaneously.
+     * @param usage The usage flag of the ImageReader
+     * @param listener The listener used by this ImageReader to notify
+     *            callbacks.
+     */
+    protected void createDefaultImageReader(Size size, int format, int maxNumImages, long usage,
+            ImageReader.OnImageAvailableListener listener) throws Exception {
+        closeDefaultImageReader();
+
+        mReader = createImageReader(size, format, maxNumImages, usage, listener);
+        mReaderSurface = mReader.getSurface();
+        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+    }
+
+    /**
      * Create an {@link ImageReader} object.
      *
      * <p>This function creates image reader object for given format, maxImages, and size.</p>
@@ -354,6 +379,29 @@
     }
 
     /**
+     * Create an {@link ImageReader} object.
+     *
+     * <p>This function creates image reader object for given format, maxImages, usage and size.</p>
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired simultaneously.
+     * @param usage The usage flag of the ImageReader
+     * @param listener The listener used by this ImageReader to notify callbacks.
+     */
+
+    protected ImageReader createImageReader(Size size, int format, int maxNumImages, long usage,
+            ImageReader.OnImageAvailableListener listener) throws Exception {
+        ImageReader reader = null;
+        reader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
+                format, maxNumImages, usage);
+
+        reader.setOnImageAvailableListener(listener, mHandler);
+        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+        return reader;
+    }
+
+    /**
      * Close the pending images then close current default {@link ImageReader} object.
      */
     protected void closeDefaultImageReader() {
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 8a9d92f..3dc7c8c 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -1677,9 +1677,9 @@
     private static void validateRawPrivateData(byte[] rawData, int width, int height,
             long ts, String filePath) {
         if (VERBOSE) Log.v(TAG, "Validating private raw data");
-        // Expect each RAW pixel should occupy at least one byte and no more than 2.5 bytes
+        // Expect each RAW pixel should occupy at least one byte and no more than 30 bytes
         int expectedSizeMin = width * height;
-        int expectedSizeMax = width * height * 5 / 2;
+        int expectedSizeMax = width * height * 30;
 
         assertTrue("Opaque RAW size " + rawData.length + "out of normal bound [" +
                 expectedSizeMin + "," + expectedSizeMax + "]",
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 5085bcc..15701f1 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -2427,6 +2427,13 @@
     }
 
     /**
+     * Check if active physical camera Id metadata is supported.
+     */
+    public boolean isActivePhysicalCameraIdSupported() {
+        return areKeysAvailable(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+    }
+
+    /**
      * Get the value in index for a fixed-size array from a given key.
      *
      * <p>If the camera device is incorrectly reporting values, log a warning and return
diff --git a/tests/contentcaptureservice/Android.mk b/tests/contentcaptureservice/Android.mk
index 48254ef..e6f42ac 100644
--- a/tests/contentcaptureservice/Android.mk
+++ b/tests/contentcaptureservice/Android.mk
@@ -26,7 +26,8 @@
     androidx.annotation_annotation \
     compatibility-device-util \
     ctstestrunner \
-    truth-prebuilt
+    truth-prebuilt \
+    testng # TODO: remove once Android migrates to JUnit 4.12, which provide assertThrows
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/contentcaptureservice/AndroidManifest.xml b/tests/contentcaptureservice/AndroidManifest.xml
index 47c62c4..11dc7ff 100644
--- a/tests/contentcaptureservice/AndroidManifest.xml
+++ b/tests/contentcaptureservice/AndroidManifest.xml
@@ -33,6 +33,16 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".BlankWithTitleActivity"
+                  android:label="Blanka"
+                  android:taskAffinity=".BlankWithTitleActivity">
+            <intent-filter>
+                <!-- This intent filter is not really needed by CTS, but it makes easier to launch
+                     this app during CTS development... -->
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <activity android:name=".LoginActivity"
                   android:label="Login"
                   android:taskAffinity=".LoginActivity"
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
index b9617bb..8e248cc 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
@@ -16,6 +16,7 @@
 package android.contentcaptureservice.cts;
 
 import android.app.Activity;
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.contentcapture.ContentCaptureManager;
@@ -81,6 +82,12 @@
     }
 
     /**
+     * Asserts the events generated when this session was launched and finished,
+     * without any custom / dynamic operations in between.
+     */
+    public abstract void assertDefaultEvents(@NonNull Session session);
+
+    /**
      * Gets the real task id associated with the activity, as {@link #getTaskId()} returns
      * {@code -1} after it's gone.
      */
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
index 9290ffc..f328ca0 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
@@ -18,6 +18,7 @@
 import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 import androidx.annotation.NonNull;
@@ -48,16 +49,50 @@
 
         mRootView = findViewById(R.id.root_view);
 
+        Log.d(TAG, "Parents for " + getClass() + ": rootView=" + mRootView
+                + "\ngrandParent=" + getGrandParent()
+                + "\ngrandGrandParent=" + getGrandGrandParent()
+                + "\ndecorView=" + getDecorView());
+
         if (sRootViewVisitor != null) {
             Log.d(TAG, "Applying visitor to " + this + "/" + mRootView);
             sRootViewVisitor.visit(this, mRootView);
         }
     }
 
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        Log.d(TAG, "AutofillIds for " + getClass() + ": "
+                + " rootView=" + getRootView().getAutofillId()
+                + ", grandParent=" + getGrandParent().getAutofillId()
+                + ", grandGrandParent=" + getGrandGrandParent().getAutofillId()
+                + ", decorView=" + getDecorView().getAutofillId());
+    }
+
     public LinearLayout getRootView() {
         return mRootView;
     }
 
+    // TODO(b/122315042): remove this method when not needed anymore
+    @NonNull
+    public ViewGroup getGrandParent() {
+        return (ViewGroup) mRootView.getParent();
+    }
+
+    // TODO(b/122315042): remove this method when not needed anymore
+    @NonNull
+    public ViewGroup getGrandGrandParent() {
+        return (ViewGroup) getGrandParent().getParent();
+    }
+
+    // TODO(b/122315042): remove this method when not needed anymore
+    @NonNull
+    public ViewGroup getDecorView() {
+        return (ViewGroup) getGrandGrandParent().getParent();
+    }
+
     /**
      * The real "onCreate" method that should be extended by subclasses.
      *
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
index 8c77521..f5366f6 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
@@ -16,6 +16,7 @@
 package android.contentcaptureservice.cts;
 
 import static android.contentcaptureservice.cts.Helper.MY_EPOCH;
+import static android.contentcaptureservice.cts.Helper.TAG;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
@@ -25,6 +26,7 @@
 
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.net.Uri;
+import android.util.Log;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ContentCaptureEvent;
@@ -35,7 +37,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -62,7 +63,7 @@
      */
     public static void assertMainSessionContext(@NonNull Session session,
             @NonNull AbstractContentCaptureActivity activity) {
-        assertMainSessionContext(session, activity, /* flags= */ 0);
+        assertMainSessionContext(session, activity, /* expectedFlags= */ 0);
     }
 
     /**
@@ -140,11 +141,9 @@
     public static ViewNode assertViewWithUnknownParentAppeared(
             @NonNull List<ContentCaptureEvent> events, int index, @NonNull View expectedView,
             @Nullable String expectedText) {
-        final ContentCaptureEvent event = getEvent(events, index);
-        assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
-                .isEqualTo(TYPE_VIEW_APPEARED);
-        final ViewNode node = event.getViewNode();
-        assertThat(node).isNotNull();
+        final ViewNode node = assertViewAppeared(events, index);
+        final ContentCaptureEvent event = events.get(index);
+
         assertWithMessage("invalid time on %s (%s)", event, index).that(event.getEventTime())
                 .isAtLeast(MY_EPOCH);
         assertWithMessage("wrong class on %s (%s)", event, index).that(node.getClassName())
@@ -161,6 +160,19 @@
     }
 
     /**
+     * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event, without checking for parent id.
+     */
+    public static ViewNode assertViewAppeared(@NonNull List<ContentCaptureEvent> events,
+            int index) {
+        final ContentCaptureEvent event = getEvent(events, index);
+        assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
+                .isEqualTo(TYPE_VIEW_APPEARED);
+        final ViewNode node = event.getViewNode();
+        assertThat(node).isNotNull();
+        return node;
+    }
+
+    /**
      * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event.
      */
     public static void assertViewAppeared(@NonNull List<ContentCaptureEvent> events, int index,
@@ -191,6 +203,18 @@
     }
 
     /**
+     * Asserts that a session for the given activity has no events.
+     */
+    public static void assertNoEvents(@NonNull Session session,
+            @NonNull AbstractContentCaptureActivity activity) {
+        assertRightActivity(session, session.id, activity);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(TAG, "events on " + activity + ": " + events);
+        assertThat(events).isEmpty();
+    }
+
+    /**
      * Asserts that the events received by the service optionally contains the
      * {@code TYPE_VIEW_DISAPPEARED} events, as they might have not been generated if the views
      * disappeared after the activity stopped.
@@ -203,25 +227,13 @@
     public static void assertViewsOptionallyDisappeared(@NonNull List<ContentCaptureEvent> events,
             int minimumSize, @NonNull AutofillId... expectedIds) {
         final int actualSize = events.size();
-        final int optionalSize = expectedIds.length;
         if (actualSize == minimumSize) {
             // Activity stopped before TYPE_VIEW_DISAPPEARED were sent.
             return;
         }
-
-        assertThat(events).hasSize(minimumSize + optionalSize);
-        final ArrayList<AutofillId> actualIds = new ArrayList<>(optionalSize);
-        final StringBuilder errors = new StringBuilder();
-        for (int i = 0; i < optionalSize; i++) {
-            final int index = minimumSize + i;
-            final ContentCaptureEvent event = getEvent(events, index);
-            if (event.getType() != TYPE_VIEW_DISAPPEARED) {
-                errors.append("Invalid event at index ").append(index).append(": ").append(event)
-                        .append('\n');
-                continue;
-            }
-            actualIds.add(event.getId());
-        }
+        assertThat(events).hasSize(minimumSize + 1);
+        final ContentCaptureEvent batchDisappearEvent = events.get(minimumSize);
+        final List<AutofillId> actualIds = batchDisappearEvent.getIds();
         assertThat(actualIds).containsExactly((Object[]) expectedIds);
     }
 
@@ -236,10 +248,34 @@
     }
 
     /**
-     * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event.
+     * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for a single view.
      */
     public static void assertViewDisappeared(@NonNull List<ContentCaptureEvent> events, int index,
             @NonNull AutofillId expectedId) {
+        final ContentCaptureEvent event = assertCommonViewDisappearedProperties(events, index);
+        assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
+            .that(event.getId()).isEqualTo(expectedId);
+        assertWithMessage("event %s (index %s) should not have autofillIds", event, index)
+            .that(event.getIds()).isNull();
+    }
+
+    /**
+     * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for multiple views.
+     */
+    public static void assertViewsDisappeared(@NonNull List<ContentCaptureEvent> events, int index,
+            @NonNull AutofillId... expectedIds) {
+        final ContentCaptureEvent event = assertCommonViewDisappearedProperties(events, index);
+        final List<AutofillId> ids = event.getIds();
+        assertWithMessage("no autofillIds on event %s (index %s)", event, index).that(ids)
+                .isNotNull();
+        assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
+            .that(ids).containsExactly((Object[]) expectedIds).inOrder();
+        assertWithMessage("event %s (index %s) should not have autofillId", event, index)
+            .that(event.getId()).isNull();
+    }
+
+    private static ContentCaptureEvent assertCommonViewDisappearedProperties(
+            @NonNull List<ContentCaptureEvent> events, int index) {
         final ContentCaptureEvent event = getEvent(events, index);
         assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
                 .isEqualTo(TYPE_VIEW_DISAPPEARED);
@@ -249,12 +285,9 @@
                 .that(event.getViewNode()).isNull();
         assertWithMessage("event %s (index %s) should not have text", event, index)
             .that(event.getText()).isNull();
-        assertWithMessage("event %s (index %s) should not have flags", event, index)
-            .that(event.getFlags()).isEqualTo(0);
         assertWithMessage("event %s (index %s) should not have a ViewNode", event, index)
             .that(event.getViewNode()).isNull();
-        assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
-            .that(event.getId()).isEqualTo(expectedId);
+        return event;
     }
 
     /**
@@ -287,9 +320,22 @@
      */
     public static void assertVirtualViewDisappeared(@NonNull List<ContentCaptureEvent> events,
             int index, @NonNull AutofillId parentId, @NonNull ContentCaptureSession session,
-            int childId) {
-        final AutofillId expectedId = session.newAutofillId(parentId, childId);
-        assertViewDisappeared(events, index, expectedId);
+            long childId) {
+        assertViewDisappeared(events, index, session.newAutofillId(parentId, childId));
+    }
+
+    /**
+     * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for many virtual nodes.
+     */
+    public static void assertVirtualViewsDisappeared(@NonNull List<ContentCaptureEvent> events,
+            int index, @NonNull AutofillId parentId, @NonNull ContentCaptureSession session,
+            long... childrenIds) {
+        final int size = childrenIds.length;
+        final AutofillId[] expectedIds = new AutofillId[size];
+        for (int i = 0; i < childrenIds.length; i++) {
+            expectedIds[i] = session.newAutofillId(parentId, childrenIds[i]);
+        }
+        assertViewsDisappeared(events, index, expectedIds);
     }
 
     /**
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
index 6fd9c2a..6ccbae9 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
@@ -15,6 +15,16 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertNoEvents;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+
+import androidx.annotation.NonNull;
+
 public class BlankActivity extends AbstractContentCaptureActivity {
 
+    @Override
+    public void assertDefaultEvents(@NonNull Session session) {
+        assertNoEvents(session, this);
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
index ddbd0b7..3597ae6 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
@@ -15,7 +15,6 @@
  */
 package android.contentcaptureservice.cts;
 
-import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
 import static android.contentcaptureservice.cts.CtsContentCaptureService.CONTENT_CAPTURE_SERVICE_COMPONENT_NAME;
 import static android.contentcaptureservice.cts.Helper.resetService;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
@@ -27,12 +26,9 @@
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
-import android.view.contentcapture.ContentCaptureEvent;
 
 import org.junit.Test;
 
-import java.util.List;
-
 public class BlankActivityTest extends AbstractContentCaptureIntegrationTest<BlankActivity> {
 
     private static final String TAG = BlankActivityTest.class.getSimpleName();
@@ -63,11 +59,7 @@
         final Session session = service.getOnlyFinishedSession();
         Log.v(TAG, "session id: " + session.id);
 
-        assertRightActivity(session, session.id, activity);
-
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        assertThat(events).isEmpty();
+        activity.assertDefaultEvents(session);
     }
 
     @Test
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
new file mode 100644
index 0000000..256b502
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.ViewNode;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+public class BlankWithTitleActivity extends AbstractContentCaptureActivity {
+
+    @Override
+    public void assertDefaultEvents(@NonNull Session session) {
+        final ContentCaptureSessionId sessionId = session.id;
+        assertRightActivity(session, sessionId, this);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(mTag, "events: " + events);
+
+        final int minEvents = 1;
+        // TODO(b/119638528): somehow asset the grandparents...
+        assertThat(events.size()).isAtLeast(minEvents);
+
+        final ViewNode title = assertViewAppeared(events, 0);
+        assertThat(title.getText()).isEqualTo("Blanka");
+    }
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
new file mode 100644
index 0000000..e08371c
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
+import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.support.test.rule.ActivityTestRule;
+import android.util.Log;
+
+import org.junit.Test;
+
+public class BlankWithTitleActivityTest
+        extends AbstractContentCaptureIntegrationTest<BlankWithTitleActivity> {
+
+    private static final String TAG = BlankWithTitleActivityTest.class.getSimpleName();
+
+    private static final ActivityTestRule<BlankWithTitleActivity> sActivityRule =
+            new ActivityTestRule<>(BlankWithTitleActivity.class, false, false);
+
+    public BlankWithTitleActivityTest() {
+        super(BlankWithTitleActivity.class);
+    }
+
+    @Override
+    protected ActivityTestRule<BlankWithTitleActivity> getActivityTestRule() {
+        return sActivityRule;
+    }
+
+    @Test
+    public void testSimpleSessionLifecycle() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        final BlankWithTitleActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        Log.v(TAG, "session id: " + session.id);
+
+        activity.assertDefaultEvents(session);
+    }
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
index f13c199..153c4c0 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
@@ -15,12 +15,24 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertNoEvents;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.os.Bundle;
 
+import androidx.annotation.NonNull;
+
 public class ChildlessActivity extends AbstractRootViewActivity {
 
     @Override
     protected void setContentViewOnCreate(Bundle savedInstanceState) {
         setContentView(R.layout.childless_activity);
     }
+
+    @Override
+    public void assertDefaultEvents(@NonNull Session session) {
+        // Should be empty because the root view is not important for content capture without a
+        // child that is important.
+        assertNoEvents(session, this);
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index d429a35..40c1420 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -24,7 +24,9 @@
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewDisappeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewsDisappeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
@@ -33,6 +35,7 @@
 import android.content.Context;
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.contentcaptureservice.cts.common.ActivityLauncher;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.support.test.rule.ActivityTestRule;
@@ -49,8 +52,10 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -89,19 +94,85 @@
         watcher.waitFor(DESTROYED);
 
         final Session session = service.getOnlyFinishedSession();
-        final ContentCaptureSessionId sessionId = session.id;
-        Log.v(TAG, "session id: " + sessionId);
+        Log.v(TAG, "session id: " + session.id);
 
-        assertRightActivity(session, sessionId, activity);
-
-        // Should be empty because the root view is not important for content capture without a
-        // child that is important.
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        assertThat(events).isEmpty();
+        activity.assertDefaultEvents(session);
     }
 
     @Test
+    public void testLaunchAnotherActivity() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher1 = startWatcher();
+
+        // Launch and finish 1st activity
+        final ChildlessActivity activity1 = launchActivity();
+        watcher1.waitFor(RESUMED);
+        activity1.finish();
+        watcher1.waitFor(DESTROYED);
+
+        // Launch and finish 2nd activity
+        final ActivityLauncher<LoginActivity> anotherActivityLauncher = new ActivityLauncher<>(
+                sContext, mActivitiesWatcher, LoginActivity.class);
+        final ActivityWatcher watcher2 = anotherActivityLauncher.getWatcher();
+        final LoginActivity activity2 = anotherActivityLauncher.launchActivity();
+        watcher2.waitFor(RESUMED);
+        activity2.finish();
+        watcher2.waitFor(DESTROYED);
+
+        // Assert the sessions
+        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+        assertThat(sessionIds).hasSize(2);
+        final ContentCaptureSessionId sessionId1 = sessionIds.get(0);
+        Log.v(TAG, "session id1: " + sessionId1);
+        final ContentCaptureSessionId sessionId2 = sessionIds.get(1);
+        Log.v(TAG, "session id2: " + sessionId2);
+
+        final Session session1 = service.getFinishedSession(sessionId1);
+        activity1.assertDefaultEvents(session1);
+
+        final Session session2 = service.getFinishedSession(sessionId2);
+        activity2.assertDefaultEvents(session2);
+    }
+
+    @Ignore("not implemented yet, pending on b/122595322")
+    @Test
+    public void testLaunchAnotherActivity_serviceDisabledActivity() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher1 = startWatcher();
+
+        // Disable activity 2
+        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+        // Launch and finish 1st activity
+        final ChildlessActivity activity1 = launchActivity();
+        watcher1.waitFor(RESUMED);
+        activity1.finish();
+        watcher1.waitFor(DESTROYED);
+
+        // Launch and finish 2nd activity
+        final ActivityLauncher<LoginActivity> anotherActivityLauncher = new ActivityLauncher<>(
+                sContext, mActivitiesWatcher, LoginActivity.class);
+        final ActivityWatcher watcher2 = anotherActivityLauncher.getWatcher();
+        final LoginActivity activity2 = anotherActivityLauncher.launchActivity();
+        watcher2.waitFor(RESUMED);
+        activity2.finish();
+        watcher2.waitFor(DESTROYED);
+
+        // Assert the sessions
+        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+        assertThat(sessionIds).hasSize(1);
+        final ContentCaptureSessionId sessionId1 = sessionIds.get(0);
+        Log.v(TAG, "session id1: " + sessionId1);
+
+        final Session session1 = service.getFinishedSession(sessionId1);
+        activity1.assertDefaultEvents(session1);
+
+        // TODO(b/122595322): should also test events after re-enabling it
+    }
+
+    // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
+
+    @Test
     public void testAddAndRemoveNoImportantChild() throws Exception {
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
@@ -481,7 +552,7 @@
 
         final TextView s3c1 = addChild(activity, childSession3, "s3c1");
         final TextView s3c2 = addChild(activity, childSession3, "s3c2");
-        waitAndRemoveView(activity, s3c1);
+        waitAndRemoveViews(activity, s3c1);
         final TextView s3c3 = addChild(activity, childSession3, "s3c3");
 
         // ...and close it right away
@@ -719,6 +790,84 @@
         assertLifecycleOrder(10, mainTestSession,  DESTRUCTION);
     }
 
+    /**
+     * Tests scenario where views from different session are removed in sequence - they should not
+     * have been batched.
+     */
+    @Test
+    public void testRemoveChildrenFromDifferentSessions() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        final ChildlessActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+        final ContentCaptureSession mainSession = activity.getRootView().getContentCaptureSession();
+        final ContentCaptureSessionId mainSessionId = mainSession.getContentCaptureSessionId();
+        Log.v(TAG, "main session id: " + mainSessionId);
+
+        // Create 1st session
+        final ContentCaptureContext context1 = new ContentCaptureContext.Builder()
+                .setUri(Uri.parse("http://session1")).build();
+        final ContentCaptureSession childSession1 = mainSession
+                .createContentCaptureSession(context1);
+        final ContentCaptureSessionId childSessionId1 = childSession1.getContentCaptureSessionId();
+        Log.v(TAG, "child session id 1: " + childSessionId1);
+
+        // Session 1, child 1
+        final TextView s1c1 = addChild(activity, childSession1, "s1c1");
+        final AutofillId s1c1Id = s1c1.getAutofillId();
+        Log.v(TAG, "childrens from session1: " + s1c1Id);
+
+        // Create 2nd session
+        final ContentCaptureContext context2 = new ContentCaptureContext.Builder()
+                .setUri(Uri.parse("http://session2")).build();
+        final ContentCaptureSession childSession2 = mainSession
+                .createContentCaptureSession(context2);
+        final ContentCaptureSessionId childSessionId2 = childSession2.getContentCaptureSessionId();
+        Log.v(TAG, "child session id 2: " + childSessionId2);
+
+        final TextView s2c1 = addChild(activity, childSession2, "s2c1");
+        final AutofillId s2c1Id = s2c1.getAutofillId();
+        final TextView s2c2 = addChild(activity, childSession2, "s2c2");
+        final AutofillId s2c2Id = s2c2.getAutofillId();
+        Log.v(TAG, "childrens from session2: " + s2c1Id + ", " + s2c2Id);
+
+        // Remove views - should generate one batch event for s2 and one single event for s1
+        waitAndRemoveViews(activity, s2c1, s2c2, s1c1);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final List<ContentCaptureSessionId> receivedIds = service.getAllSessionIds();
+        assertThat(receivedIds).containsExactly(
+                mainSessionId,
+                childSessionId1,
+                childSessionId2)
+            .inOrder();
+
+        // Assert main sessions info
+        final Session mainTestSession = service.getFinishedSession(mainSessionId);
+        assertMainSessionContext(mainTestSession, activity);
+
+        final Session childTestSession1 = service.getFinishedSession(childSessionId1);
+        assertChildSessionContext(childTestSession1, "http://session1");
+        final List<ContentCaptureEvent> events1 = childTestSession1.getEvents();
+        Log.v(TAG, "events1: " + events1);
+        assertThat(events1.size()).isAtLeast(2);
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+        assertViewAppeared(events1, 0, s1c1, rootId);
+        assertViewDisappeared(events1, 1, s1c1Id);
+
+        final Session childTestSession2 = service.getFinishedSession(childSessionId2);
+        final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
+        assertChildSessionContext(childTestSession2, "http://session2");
+        Log.v(TAG, "events2: " + events2);
+        assertThat(events2.size()).isAtLeast(3);
+        assertViewAppeared(events2, 0, s2c1, rootId);
+        assertViewAppeared(events2, 1, s2c2, rootId);
+        assertViewsDisappeared(events2, 2, s2c1Id, s2c2Id);
+    }
+
     /* TODO(b/119638528): add more scenarios for nested sessions, such as:
      * - add views to the children sessions
      * - s1 -> s2 -> s3 and main -> s4; close(s1) then generate events on view from s3
@@ -744,8 +893,8 @@
         return child;
     }
 
-    // TODO(b/119638958): these method are used in cases where we cannot close a session because we
-    // would miss intermediate evets, so we need to sleep. This is a hack (it's slow and flaky):
+    // TODO(b/123024698): these method are used in cases where we cannot close a session because we
+    // would miss intermediate events, so we need to sleep. This is a hack (it's slow and flaky):
     // ideally we should block and wait until the service receives the event, but right now
     // we don't get the service events until after the activity is finished, so we cannot do that...
     private void waitAndClose(@NonNull ContentCaptureSession session) {
@@ -753,9 +902,14 @@
         SystemClock.sleep(1_000);
         session.close();
     }
-    private void waitAndRemoveView(@NonNull ChildlessActivity activity, @NonNull View view) {
-        Log.d(TAG, "sleeping for 1s before removing " + view.getAutofillId());
+
+    private void waitAndRemoveViews(@NonNull ChildlessActivity activity, @NonNull View... views) {
+        Log.d(TAG, "sleeping for 1s before removing " + Arrays.toString(views));
         SystemClock.sleep(1_000);
-        activity.syncRunOnUiThread(() -> activity.getRootView().removeView(view));
+        activity.syncRunOnUiThread(() -> {
+            for (View view : views) {
+                activity.getRootView().removeView(view);
+            }
+        });
     }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java
new file mode 100644
index 0000000..c19f0f7
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.platform.test.annotations.AppModeFull;
+import android.view.contentcapture.ContentCaptureContext;
+import android.view.contentcapture.ContentCaptureContext.Builder;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+@AppModeFull // Unit test
+public class ContentCaptureContextTest {
+
+    private static final Uri URI = Uri.parse("file:/dev/null");
+    private static final String ACTION = "Jackson";
+
+    private final ContentCaptureContext.Builder mBuilder = new ContentCaptureContext.Builder();
+
+    private final Bundle mExtras = new Bundle();
+
+    @Before
+    public void setExtras() {
+        mExtras.putString("DUDE", "SWEET");
+    }
+
+    @Test
+    public void testBuilder_invalidUri() {
+        assertThrows(NullPointerException.class, () -> mBuilder.setUri(null));
+    }
+
+    @Test
+    public void testBuilder_invalidAction() {
+        assertThrows(NullPointerException.class, () -> mBuilder.setAction(null));
+    }
+
+    @Test
+    public void testBuilder_invalidExtras() {
+        assertThrows(NullPointerException.class, () -> mBuilder.setExtras(null));
+    }
+
+    @Test
+    public void testAfterBuild_setExtras() {
+        assertThat(mBuilder.setUri(URI).build()).isNotNull();
+        assertThrows(IllegalStateException.class, () -> mBuilder.setExtras(mExtras));
+    }
+
+    @Test
+    public void testAfterBuild_setAction() {
+        assertThat(mBuilder.setUri(URI).build()).isNotNull();
+        assertThrows(IllegalStateException.class, () -> mBuilder.setAction(ACTION));
+    }
+
+    @Test
+    public void testAfterBuild_setUri() {
+        assertThat(mBuilder.setExtras(mExtras).build()).isNotNull();
+        assertThrows(IllegalStateException.class, () -> mBuilder.setUri(URI));
+    }
+
+    @Test
+    public void testAfterBuild_build() {
+        assertThat(mBuilder.setExtras(mExtras).build()).isNotNull();
+        assertThrows(IllegalStateException.class, () -> mBuilder.build());
+    }
+
+    @Test
+    public void testBuild_empty() {
+        assertThrows(IllegalStateException.class, () -> mBuilder.build());
+    }
+
+    @Test
+    public void testSetGetUri() {
+        final Builder builder = mBuilder.setUri(URI);
+        assertThat(builder).isSameAs(mBuilder);
+        final ContentCaptureContext context = builder.build();
+        assertThat(context).isNotNull();
+        assertThat(context.getUri()).isEqualTo(URI);
+    }
+
+    @Test
+    public void testSetGetAction() {
+        final Builder builder = mBuilder.setAction(ACTION);
+        assertThat(builder).isSameAs(mBuilder);
+        final ContentCaptureContext context = builder.build();
+        assertThat(context).isNotNull();
+        assertThat(context.getAction()).isEqualTo(ACTION);
+    }
+
+    @Test
+    public void testGetSetBundle() {
+        final Builder builder = mBuilder.setExtras(mExtras);
+        assertThat(builder).isSameAs(mBuilder);
+        final ContentCaptureContext context = builder.build();
+        assertThat(context).isNotNull();
+        assertExtras(context.getExtras());
+    }
+
+    @Test
+    public void testParcel() {
+        final Builder builder = mBuilder
+                .setUri(URI)
+                .setAction(ACTION)
+                .setExtras(mExtras);
+        assertThat(builder).isSameAs(mBuilder);
+        final ContentCaptureContext context = builder.build();
+        assertEverything(context);
+
+        final ContentCaptureContext clone = cloneThroughParcel(context);
+        assertEverything(clone);
+    }
+
+    private void assertEverything(@NonNull ContentCaptureContext context) {
+        assertThat(context).isNotNull();
+        assertThat(context.getUri()).isEqualTo(URI);
+        assertThat(context.getAction()).isEqualTo(ACTION);
+        assertExtras(context.getExtras());
+    }
+
+    private void assertExtras(@NonNull Bundle bundle) {
+        assertThat(bundle).isNotNull();
+        assertThat(bundle.keySet()).hasSize(1);
+        assertThat(bundle.getString("DUDE")).isEqualTo("SWEET");
+    }
+
+    private ContentCaptureContext cloneThroughParcel(@NonNull ContentCaptureContext context) {
+        final Parcel parcel = Parcel.obtain();
+
+        try {
+            // Write to parcel
+            parcel.setDataPosition(0); // Sanity / paranoid check
+            context.writeToParcel(parcel, 0);
+
+            // Read from parcel
+            parcel.setDataPosition(0);
+            final ContentCaptureContext clone = ContentCaptureContext.CREATOR
+                    .createFromParcel(parcel);
+            assertThat(clone).isNotNull();
+            return clone;
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
index b8b367a..bbbbc0f 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
@@ -17,17 +17,18 @@
 
 import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
 import static android.contentcaptureservice.cts.Helper.await;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.content.ComponentName;
-import android.service.contentcapture.ContentCaptureEventsRequest;
 import android.service.contentcapture.ContentCaptureService;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureEvent;
 import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.UserDataRemovalRequest;
 import android.view.contentcapture.ViewNode;
 
 import androidx.annotation.NonNull;
@@ -51,7 +52,7 @@
     public static final String SERVICE_NAME = MY_PACKAGE + "/."
             + CtsContentCaptureService.class.getSimpleName();
     public static final ComponentName CONTENT_CAPTURE_SERVICE_COMPONENT_NAME =
-            new ComponentName(MY_PACKAGE, CtsContentCaptureService.class.getName());
+            componentNameFor(CtsContentCaptureService.class);
 
     private static ServiceWatcher sServiceWatcher;
 
@@ -90,6 +91,11 @@
      */
     private int mLifecycleEventsCounter;
 
+    /**
+     * Used for testing onUserDataRemovalRequest.
+     */
+    private UserDataRemovalRequest mRemovalRequest;
+
     @NonNull
     public static ServiceWatcher setServiceWatcher() {
         if (sServiceWatcher != null) {
@@ -214,26 +220,32 @@
     }
 
     @Override
-    public void onContentCaptureEventsRequest(ContentCaptureSessionId sessionId,
-            ContentCaptureEventsRequest request) {
-        final List<ContentCaptureEvent> events = request.getEvents();
-        final int size = events.size();
-        Log.i(TAG, "onContentCaptureEventsRequest(" + sessionId + "): " + size + " events");
-        for (int i = 0; i < size; i++) {
-            final ContentCaptureEvent event = events.get(i);
-            final StringBuilder msg = new StringBuilder("  ").append(i).append(": ").append(event);
-            final ViewNode node = event.getViewNode();
-            if (node != null) {
-                msg.append(", parent=").append(node.getParentAutofillId());
-            }
-            Log.v(TAG, msg.toString());
+    public void onContentCaptureEvent(ContentCaptureSessionId sessionId,
+            ContentCaptureEvent event) {
+        Log.i(TAG, "onContentCaptureEvent(" + sessionId + "): " + event);
+        final ViewNode node = event.getViewNode();
+        if (node != null) {
+            Log.v(TAG, "onContentCaptureEvent(): parentId=" + node.getParentAutofillId());
         }
         safeRun(() -> {
             final Session session = getExistingSession(sessionId);
-            session.mRequests.add(request);
+            session.mEvents.add(event);
         });
     }
 
+    @Override
+    public void onUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) {
+        Log.i(TAG, "onUserDataRemovalRequest(" + request + ")");
+        mRemovalRequest = request;
+    }
+
+    /**
+     * Gets the cached UserDataRemovalRequest for testing.
+     */
+    public UserDataRemovalRequest getRemovalRequest() {
+        return mRemovalRequest;
+    }
+
     /**
      * Gets the finished session for the given session id.
      *
@@ -343,7 +355,7 @@
         public final ContentCaptureSessionId id;
         public final ContentCaptureContext context;
         public final int creationOrder;
-        private final List<ContentCaptureEventsRequest> mRequests = new ArrayList<>();
+        private final List<ContentCaptureEvent> mEvents = new ArrayList<>();
         public boolean finished;
         public int destructionOrder;
 
@@ -364,16 +376,12 @@
         // should track individual requests as well to make sure they're probably batch (it will
         // require adding a Settings to tune the buffer parameters.
         public List<ContentCaptureEvent> getEvents() {
-            final List<ContentCaptureEvent> events = new ArrayList<>();
-            for (ContentCaptureEventsRequest request : mRequests) {
-                events.addAll(request.getEvents());
-            }
-            return Collections.unmodifiableList(events);
+            return Collections.unmodifiableList(mEvents);
         }
 
         @Override
         public String toString() {
-            return "[id=" + id + ", context=" + context + ", requests=" + mRequests.size()
+            return "[id=" + id + ", context=" + context + ", events=" + mEvents.size()
                     + ", finished=" + finished + "]";
         }
     }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
index edbd453..5fb5fbf 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
@@ -15,13 +15,22 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.ViewStructure;
+import android.view.contentcapture.ContentCaptureEvent;
 
 import androidx.annotation.NonNull;
 
+import java.util.List;
+
 public class CustomViewActivity extends AbstractContentCaptureActivity {
 
     private static final String TAG = CustomViewActivity.class.getSimpleName();
@@ -50,4 +59,19 @@
                     (structure) -> sCustomViewDelegate.visit(mCustomView, structure));
         }
     }
+
+    @Override
+    public void assertDefaultEvents(@NonNull Session session) {
+        assertRightActivity(session, session.id, this);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(TAG, "events: " + events);
+        // TODO(b/119638528): check right number once we get rid of grandparent
+        assertThat(events.size()).isAtLeast(1);
+
+        // Assert just the relevant events
+        assertViewWithUnknownParentAppeared(events, 0, session.id, mCustomView);
+
+        // TODO(b/122315042): assert views disappeared
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
index 6476faf..c7afd2a 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
@@ -19,6 +19,8 @@
 import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertVirtualViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertVirtualViewDisappeared;
+import static android.contentcaptureservice.cts.Assertions.assertVirtualViewsDisappeared;
+import static android.contentcaptureservice.cts.Helper.await;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
@@ -40,7 +42,9 @@
 
 import org.junit.Test;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 
 public class CustomViewActivityTest extends
         AbstractContentCaptureIntegrationTest<CustomViewActivity> {
@@ -76,17 +80,7 @@
         final Session session = service.getOnlyFinishedSession();
         Log.v(TAG, "session id: " + session.id);
 
-        assertRightActivity(session, session.id, activity);
-
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent
-        assertThat(events.size()).isAtLeast(1);
-
-        // Assert just the relevant events
-        assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
-
-        // TODO(b/122315042): assert views disappeared
+        activity.assertDefaultEvents(session);
     }
 
     /**
@@ -153,7 +147,7 @@
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
 
-        setAsyncDelegate((customView, structure) -> {
+        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
             Log.d(TAG, "delegate running on " + Thread.currentThread());
             final AutofillId customViewId = customView.getAutofillId();
             Log.d(TAG, "customViewId: " + customViewId);
@@ -165,14 +159,12 @@
             assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
             Log.d(TAG, "nofifying child1 appeared: " + child1Id);
             session.notifyViewAppeared(child1);
-
             final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
             child2.setText("child2");
             final AutofillId child2Id = child2.getAutofillId();
             assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
             Log.d(TAG, "nofifying child2 appeared: " + child2Id);
             session.notifyViewAppeared(child2);
-
             Log.d(TAG, "nofifying child2 disappeared: " + child2Id);
             session.notifyViewDisappeared(child2Id);
             Log.d(TAG, "nofifying child1 disappeared: " + child1Id);
@@ -181,6 +173,7 @@
 
         final CustomViewActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
+        await(asyncLatch, "async onProvide");
 
         activity.finish();
         watcher.waitFor(DESTROYED);
@@ -192,8 +185,8 @@
 
         final List<ContentCaptureEvent> events = session.getEvents();
         Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent (should be 5)
-        assertThat(events.size()).isAtLeast(7);
+        // TODO(b/119638528): check right number once we get rid of grandparent
+        assertThat(events.size()).isAtLeast(6);
 
         // Assert just the relevant events
         final AutofillId customViewId = activity.mCustomView.getAutofillId();
@@ -203,8 +196,7 @@
         // TODO(b/119638528): next 2 events are the grandparents
         assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
         assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
-        assertVirtualViewDisappeared(events, 5, customViewId, mainSession, 2);
-        assertVirtualViewDisappeared(events, 6, customViewId, mainSession, 1);
+        assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
 
         // TODO(b/122315042): assert views disappeared
     }
@@ -217,7 +209,7 @@
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
 
-        setAsyncDelegate((customView, structure) -> {
+        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
             Log.d(TAG, "delegate running on " + Thread.currentThread());
             final AutofillId customViewId = customView.getAutofillId();
             Log.d(TAG, "customViewId: " + customViewId);
@@ -296,7 +288,7 @@
 
         final CustomViewActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
-
+        await(asyncLatch, "async onProvide");
         activity.finish();
         watcher.waitFor(DESTROYED);
 
@@ -308,7 +300,7 @@
         final List<ContentCaptureEvent> events = session.getEvents();
         Log.v(TAG, "events: " + events);
         // TODO(b/119638528): check right number once we get rid of grandparents
-        assertThat(events.size()).isAtLeast(15);
+        assertThat(events.size()).isAtLeast(11);
 
         // Assert just the relevant events
         final AutofillId customViewId = activity.mCustomView.getAutofillId();
@@ -323,24 +315,85 @@
         assertVirtualViewAppeared(events, 7, mainSession, customViewId, 21, "c2g1");
         assertVirtualViewAppeared(events, 8, mainSession, customViewId, 211, "c2g1gg1");
         assertVirtualViewAppeared(events, 9, mainSession, customViewId, 3, "c3");
-        assertVirtualViewDisappeared(events, 10, customViewId, mainSession, 21);
-        assertVirtualViewDisappeared(events, 11, customViewId, mainSession, 2);
-        assertVirtualViewDisappeared(events, 12, customViewId, mainSession, 11);
-        assertVirtualViewDisappeared(events, 13, customViewId, mainSession, 1);
-        assertVirtualViewDisappeared(events, 14, customViewId, mainSession, 12);
+        assertVirtualViewsDisappeared(events, 10, customViewId, mainSession, 21, 2, 11, 1, 12);
 
-        // TODO(b/122315042): assert views disappeared
+        // TODO(b/122315042): assert other views disappeared
     }
 
     // TODO(b/119638528): add tests for multiple sessions
 
+    @Test
+    public void testVirtualView_batchDisappear() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
+            Log.d(TAG, "delegate running on " + Thread.currentThread());
+            final AutofillId customViewId = customView.getAutofillId();
+            Log.d(TAG, "customViewId: " + customViewId);
+            final ContentCaptureSession session = customView.getContentCaptureSession();
+
+            final ViewStructure child1 = session.newVirtualViewStructure(customViewId, 1);
+            child1.setText("child1");
+            final AutofillId child1Id = child1.getAutofillId();
+            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
+            Log.d(TAG, "nofifying child1 appeared: " + child1Id);
+            session.notifyViewAppeared(child1);
+
+            final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
+            child2.setText("child2");
+            final AutofillId child2Id = child2.getAutofillId();
+            assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
+            Log.d(TAG, "nofifying child2 appeared: " + child2Id);
+            session.notifyViewAppeared(child2);
+
+            final long[] childrenIds = {2, 1};
+            Log.d(TAG, "nofifying both children disappeared: " + Arrays.toString(childrenIds));
+            session.notifyViewsDisappeared(customViewId, childrenIds);
+        });
+
+        final CustomViewActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+        await(asyncLatch, "async onProvide");
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        Log.v(TAG, "session id: " + session.id);
+
+        assertRightActivity(session, session.id, activity);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(TAG, "events: " + events);
+        // TODO(b/119638528): check right number once we get rid of grandparent (should be 5)
+        assertThat(events.size()).isAtLeast(6);
+
+        // Assert just the relevant events
+        final AutofillId customViewId = activity.mCustomView.getAutofillId();
+        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
+
+        assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
+        // TODO(b/119638528): next 2 events are the grandparents
+        assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
+        assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
+        assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
+
+        // TODO(b/122315042): assert other views disappeared
+    }
+
     /**
      * Sets a delegate that will generate the events asynchronously,
      * after {@code onProvideContentCaptureStructure()} returns.
      */
-    private void setAsyncDelegate(@NonNull DoubleVisitor<CustomView, ViewStructure> delegate) {
+    private CountDownLatch setAsyncDelegate(
+            @NonNull DoubleVisitor<CustomView, ViewStructure> delegate) {
+        final CountDownLatch asyncLatch = new CountDownLatch(1);
         CustomViewActivity.setCustomViewDelegate(
                 (customView, structure) -> new Handler(Looper.getMainLooper())
-                        .post(() -> delegate.visit(customView, structure)));
+                        .post(() -> {
+                            delegate.visit(customView, structure);
+                            asyncLatch.countDown();
+                        }));
+        return asyncLatch;
     }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
index 79c6b40..728ee82 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
@@ -17,6 +17,7 @@
 
 import static android.contentcaptureservice.cts.common.ShellHelper.runShellCommand;
 
+import android.content.ComponentName;
 import android.os.SystemClock;
 import android.util.Log;
 
@@ -69,6 +70,13 @@
         runShellCommand("cmd content_capture set temporary-service 0");
     }
 
+    /**
+     * Gets the component name for a given class.
+     */
+    public static ComponentName componentNameFor(@NonNull Class<?> clazz) {
+        return new ComponentName(MY_PACKAGE, clazz.getName());
+    }
+
     private Helper() {
         throw new UnsupportedOperationException("contain static methods only");
     }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
index 6360651..fc9efbd 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
@@ -15,12 +15,31 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertSessionId;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureSessionId;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
 public class LoginActivity extends AbstractRootViewActivity {
 
+    private static final String TAG = LoginActivity.class.getSimpleName();
+
     TextView mUsernameLabel;
     EditText mUsername;
     TextView mPasswordLabel;
@@ -28,7 +47,6 @@
 
     @Override
     protected void setContentViewOnCreate(Bundle savedInstanceState) {
-
         setContentView(R.layout.login_activity);
 
         mUsernameLabel = findViewById(R.id.username_label);
@@ -36,4 +54,62 @@
         mPasswordLabel = findViewById(R.id.password_label);
         mPassword = findViewById(R.id.password);
     }
+
+    @Override
+    public void assertDefaultEvents(@NonNull Session session) {
+        final LoginActivity activity = this;
+        final ContentCaptureSessionId sessionId = session.id;
+        assertRightActivity(session, sessionId, activity);
+
+        // Sanity check
+        assertSessionId(sessionId, activity.mUsernameLabel);
+        assertSessionId(sessionId, activity.mUsername);
+        assertSessionId(sessionId, activity.mPassword);
+        assertSessionId(sessionId, activity.mPasswordLabel);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(mTag, "events: " + events);
+        // TODO(b/119638528): ideally it should be 5 so it reflects just the views defined
+        // in the layout - right now it's generating events for 2 intermediate parents
+        // (android:action_mode_bar_stub and android:content), we should try to create an
+        // activity without them
+
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+
+        final int minEvents = 7;
+        assertThat(events.size()).isAtLeast(minEvents);
+        assertViewAppeared(events, 0, sessionId, activity.mUsernameLabel, rootId);
+        assertViewAppeared(events, 1, sessionId, activity.mUsername, rootId);
+        assertViewAppeared(events, 2, sessionId, activity.mPasswordLabel, rootId);
+        assertViewAppeared(events, 3, sessionId, activity.mPassword, rootId);
+
+        // TODO(b/119638528): get rid of those intermediated parents
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final View decorView = activity.getDecorView();
+
+        assertViewAppeared(events, 4, sessionId, activity.getRootView(),
+                grandpa1.getAutofillId());
+        assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
+        assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
+
+        assertViewsOptionallyDisappeared(events, minEvents,
+                rootId,
+                grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
+                // generated
+                activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+                activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
+        );
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        Log.d(TAG, "AutofillIds: " + "usernameLabel=" + mUsernameLabel.getAutofillId()
+                + ", username=" + mUsername.getAutofillId()
+                + ", passwordLabel=" + mPasswordLabel.getAutofillId()
+                + ", password=" + mPassword.getAutofillId());
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
index 00da1c4..379f28f 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
@@ -23,6 +23,8 @@
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewTextChanged;
 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
@@ -41,13 +43,16 @@
 import android.view.contentcapture.ContentCaptureEvent;
 import android.view.contentcapture.ContentCaptureSession;
 import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.UserDataRemovalRequest;
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 public class LoginActivityTest extends AbstractContentCaptureIntegrationTest<LoginActivity> {
 
@@ -83,53 +88,12 @@
         watcher.waitFor(DESTROYED);
 
         final Session session = service.getOnlyFinishedSession();
-        final ContentCaptureSessionId sessionId = session.id;
-        Log.v(TAG, "session id: " + sessionId);
+        Log.v(TAG, "session id: " + session.id);
 
-        assertRightActivity(session, sessionId, activity);
-
-        // Sanity check
-        assertSessionId(sessionId, activity.mUsernameLabel);
-        assertSessionId(sessionId, activity.mUsername);
-        assertSessionId(sessionId, activity.mPassword);
-        assertSessionId(sessionId, activity.mPasswordLabel);
-
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): ideally it should be 5 so it reflects just the views defined
-        // in the layout - right now it's generating events for 2 intermediate parents
-        // (android:action_mode_bar_stub and android:content), we should try to create an
-        // activity without them
-
-        final AutofillId rootId = activity.getRootView().getAutofillId();
-
-        final int minEvents = 7;
-        assertThat(events.size()).isAtLeast(minEvents);
-        assertViewAppeared(events, 0, sessionId, activity.mUsernameLabel, rootId);
-        assertViewAppeared(events, 1, sessionId, activity.mUsername, rootId);
-        assertViewAppeared(events, 2, sessionId, activity.mPasswordLabel, rootId);
-        assertViewAppeared(events, 3, sessionId, activity.mPassword, rootId);
-
-        // TODO(b/119638528): get rid of those intermediated parents
-        final View grandpa1 = (View) activity.getRootView().getParent();
-        final View grandpa2 = (View) grandpa1.getParent();
-        final View decorView = (View) grandpa2.getParent();
-
-        assertViewAppeared(events, 4, sessionId, activity.getRootView(),
-                grandpa1.getAutofillId());
-        assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
-        assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
-
-        assertViewsOptionallyDisappeared(events, minEvents,
-                rootId,
-                grandpa1.getAutofillId(), grandpa2.getAutofillId(),
-                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
-                // generated
-                activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
-                activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
-        );
+        activity.assertDefaultEvents(session);
     }
 
+
     @Test
     public void testSimpleLifecycle_rootViewSession() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -174,13 +138,16 @@
         assertSessionId(childSessionId, activity.mPasswordLabel);
 
         // Get the sessions
-        final List<ContentCaptureSessionId> allSessionIds = service.getAllSessionIds();
-        assertThat(allSessionIds).containsExactly(mainSessionId, childSessionId);
         final Session mainSession = service.getFinishedSession(mainSessionId);
         final Session childSession = service.getFinishedSession(childSessionId);
+
         assertRightActivity(mainSession, mainSessionId, activity);
         assertRightRelationship(mainSession, childSession);
 
+        // Sanity check
+        final List<ContentCaptureSessionId> allSessionIds = service.getAllSessionIds();
+        assertThat(allSessionIds).containsExactly(mainSessionId, childSessionId);
+
         /*
          *  Asserts main session
          */
@@ -197,9 +164,9 @@
         // create an activity without them
         final int minMainEvents = 2;
         assertThat(mainEvents.size()).isAtLeast(minMainEvents);
-        final View grandpa1 = (View) activity.getRootView().getParent();
-        final View grandpa2 = (View) grandpa1.getParent();
-        final View decorView = (View) grandpa2.getParent();
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final View decorView = activity.getDecorView();
         assertViewAppeared(mainEvents, 0, grandpa1, grandpa2.getAutofillId());
         assertViewAppeared(mainEvents, 1, grandpa2, decorView.getAutofillId());
         assertViewsOptionallyDisappeared(mainEvents, minMainEvents,
@@ -238,6 +205,29 @@
         );
     }
 
+    @Ignore("not implemented yet, pending on b/122595322")
+    @Test
+    public void testSimpleLifecycle_serviceDisabledActivity() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        // Disable activity
+        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+        assertThat(sessionIds).isEmpty();
+
+        // TODO(b/122595322): should also test events after re-enabling it
+    }
+
+    // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
+
     @Test
     public void testTextChanged() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -275,9 +265,9 @@
         assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
         assertViewAppeared(events, 3, activity.mPassword, rootId, "");
         // TODO(b/119638528): get rid of those intermediated parents
-        final View grandpa1 = (View) activity.getRootView().getParent();
-        final View grandpa2 = (View) grandpa1.getParent();
-        final View decorView = (View) grandpa2.getParent();
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final View decorView = activity.getDecorView();
 
         assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
         assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
@@ -338,9 +328,9 @@
         assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
         assertViewAppeared(events, 3, activity.mPassword, rootId, "");
         // TODO(b/119638528): get rid of those intermediated parents
-        final View grandpa1 = (View) activity.getRootView().getParent();
-        final View grandpa2 = (View) grandpa1.getParent();
-        final View decorView = (View) grandpa2.getParent();
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final View decorView = activity.getDecorView();
 
         assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
         assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
@@ -352,17 +342,15 @@
 
         assertViewsOptionallyDisappeared(events, minEvents,
                 rootId,
-                grandpa1.getAutofillId(), grandpa2.getAutofillId(),
-                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
-                // generated
+                grandpa1.getAutofillId(),
+                grandpa2.getAutofillId(),
                 activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
                 activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
         );
-
     }
 
     @Test
-    public void testSimpleLifecycle_flagSecure() throws Exception {
+    public void testDisabledByFlagSecure() throws Exception {
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
 
@@ -376,6 +364,8 @@
         watcher.waitFor(DESTROYED);
 
         final Session session = service.getOnlyFinishedSession();
+        assertThat((session.context.getFlags()
+                & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0).isTrue();
         final ContentCaptureSessionId sessionId = session.id;
         Log.v(TAG, "session id: " + sessionId);
 
@@ -385,6 +375,191 @@
         assertThat(events).isEmpty();
     }
 
+    @Test
+    public void testDisabledByApp() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+                .setContentCaptureEnabled(false));
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        assertThat((session.context.getFlags()
+                & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0).isTrue();
+        final ContentCaptureSessionId sessionId = session.id;
+        Log.v(TAG, "session id: " + sessionId);
+
+        assertRightActivity(session, sessionId, activity);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        assertThat(events).isEmpty();
+    }
+
+    @Test
+    public void testDisabledFlagSecureAndByApp() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        LoginActivity.onRootView((activity, rootView) -> {
+            activity.getContentCaptureManager().setContentCaptureEnabled(false);
+            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+        });
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        assertThat((session.context.getFlags()
+                & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0).isTrue();
+        assertThat((session.context.getFlags()
+                & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0).isTrue();
+        final ContentCaptureSessionId sessionId = session.id;
+        Log.v(TAG, "session id: " + sessionId);
+
+        assertRightActivity(session, sessionId, activity);
+
+        final List<ContentCaptureEvent> events = session.getEvents();
+        assertThat(events).isEmpty();
+    }
+
+    @Ignore("not implemented yet, pending on b/122595322")
+    @Test
+    public void testDisabledByFlagSecureAndService() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getWindow()
+                .addFlags(WindowManager.LayoutParams.FLAG_SECURE));
+
+        // Disable activity
+        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+        assertThat(sessionIds).isEmpty();
+    }
+
+    @Ignore("not implemented yet, pending on b/122595322")
+    @Test
+    public void testDisabledByAppAndAndService() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+                .setContentCaptureEnabled(false));
+
+        // Disable activity
+        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+    }
+
+    @Test
+    public void testUserDataRemovalRequest_forEverything() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+                .removeUserData(new UserDataRemovalRequest.Builder().forEverything()
+                        .build()));
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        UserDataRemovalRequest request = service.getRemovalRequest();
+        assertThat(request).isNotNull();
+        assertThat(request.isForEverything()).isTrue();
+        assertThat(request.getUriRequests()).isNull();
+        assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+    }
+
+    @Test
+    public void testUserDataRemovalRequest_oneUri() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        Uri uri = Uri.parse("com.example");
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+                .removeUserData(new UserDataRemovalRequest.Builder()
+                        .addUri(uri, false)
+                        .build()));
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        UserDataRemovalRequest request = service.getRemovalRequest();
+        assertThat(request).isNotNull();
+        assertThat(request.isForEverything()).isFalse();
+
+        List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+        assertThat(requests.size()).isEqualTo(1);
+        assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
+                .containsExactly(uri).inOrder();
+        assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+    }
+
+    @Test
+    public void testUserDataRemovalRequest_manyUris() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        Uri uri = Uri.parse("com.example");
+        Uri uri2 = Uri.parse("com.example2");
+
+        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+                .removeUserData(new UserDataRemovalRequest.Builder()
+                        .addUri(uri, false)
+                        .addUri(uri2, false)
+                        .build()));
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        UserDataRemovalRequest request = service.getRemovalRequest();
+        assertThat(request).isNotNull();
+        assertThat(request.isForEverything()).isFalse();
+
+        List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+        assertThat(requests.size()).isEqualTo(2);
+        assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
+                .containsExactly(uri, uri2).inOrder();
+        assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+    }
+
     // TODO(b/119638528): add moar test cases for different sessions:
     // - session1 on rootView, session2 on children
     // - session1 on rootView, session2 on child1, session3 on child2
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
index 382e925..38a6509 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
@@ -101,6 +101,11 @@
         return watch(clazz.getName());
     }
 
+    @Override
+    public String toString() {
+        return "[ActivitiesWatcher: activities=" + mWatchers.keySet() + "]";
+    }
+
     /**
      * Gets a watcher for the given activity.
      *
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
new file mode 100644
index 0000000..d844894
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts.common;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.support.test.rule.ActivityTestRule;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Helper used to launch an activity and watch for its lifecycle events.
+ */
+public final class ActivityLauncher<A extends Activity> {
+
+    private final ActivityWatcher mWatcher;
+    private final ActivityTestRule<A> mActivityTestRule;
+    private final Intent mLaunchIntent;
+
+    public ActivityLauncher(@NonNull Context context, @NonNull ActivitiesWatcher watcher,
+            @NonNull Class<A> activityClass) {
+        mWatcher = watcher.watch(activityClass);
+        mActivityTestRule = new ActivityTestRule<>(activityClass);
+        mLaunchIntent = new Intent(context, activityClass);
+    }
+
+    @NonNull
+    public ActivityWatcher getWatcher() {
+        return mWatcher;
+    }
+
+    @NonNull
+    public A launchActivity() {
+        return mActivityTestRule.launchActivity(mLaunchIntent);
+    }
+}
diff --git a/tests/framework/base/activitymanager/Android.mk b/tests/framework/base/activitymanager/Android.mk
index 498f0a3..28f6753 100644
--- a/tests/framework/base/activitymanager/Android.mk
+++ b/tests/framework/base/activitymanager/Android.mk
@@ -42,10 +42,13 @@
     CtsMockInputMethodLib \
     metrics-helper-lib
 
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/intent_tests
+
 LOCAL_CTS_TEST_PACKAGE := android.server
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_CERTIFICATE := platform
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index 8b55608..62cebb6 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -20,6 +20,9 @@
     <uses-permission android:name="android.permission.READ_LOGS" />
     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.INJECT_EVENTS" />
+    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/>
 
     <application android:label="CtsActivityManagerDeviceTestCases">
         <uses-library android:name="android.test.runner" />
@@ -77,6 +80,8 @@
 
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$SecondActivity"/>
 
+        <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$ThirdActivity"/>
+
         <activity
                 android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$TranslucentActivity"
                 android:theme="@android:style/Theme.Translucent.NoTitleBar" />
@@ -97,12 +102,18 @@
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$ConfigChangeHandlingActivity"
                   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density" />
 
+        <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$PipActivity"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+                  android:supportsPictureInPicture="true"/>
+
         <activity android:name="android.server.am.StartActivityTests$TestActivity2" />
 
         <activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivity" />
         <activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivity2" />
         <activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivityWithBrokenContextWrapper" />
 
+        <activity android:name="android.server.am.KeyguardLockedTests$ShowWhenLockedImeActivity" />
+
         <activity android:name="android.server.am.lifecycle.ActivityStarterTests$StandardActivity"
                   android:exported="true" />
 
@@ -128,10 +139,81 @@
                   android:taskAffinity="nobody.but.LaunchingActivity"
                   android:exported="true" />
 
+        <activity android:name="android.server.am.ActivityViewTest$ActivityViewTestActivity"
+                  android:exported="true"/>
+
         <provider
             android:name="android.server.am.TestJournalProvider"
             android:authorities="android.server.am.testjournalprovider"
             android:exported="true" />
+
+        <!--intent tests-->
+        <activity android:name="android.server.am.intent.Activities$RegularActivity"/>
+        <activity
+            android:name="android.server.am.intent.Activities$SingleTopActivity"
+            android:launchMode="singleTop"/>
+        <activity
+            android:name="android.server.am.intent.Activities$SingleInstanceActivity"
+            android:launchMode="singleInstance"/>
+        <activity
+            android:name="android.server.am.intent.Activities$SingleInstanceActivity2"
+            android:launchMode="singleInstance"
+            android:taskAffinity=".t1"
+        />
+        <activity
+            android:name="android.server.am.intent.Activities$SingleTaskActivity"
+            android:launchMode="singleTask"
+        />
+        <activity
+            android:name="android.server.am.intent.Activities$SingleTaskActivity2"
+            android:launchMode="singleTask"
+            android:taskAffinity=".t1"
+        />
+        <activity
+            android:name="android.server.am.intent.Activities$TaskAffinity1Activity"
+            android:allowTaskReparenting="true"
+            android:launchMode="standard"
+            android:taskAffinity=".t1"/>
+        <activity
+            android:name="android.server.am.intent.Activities$TaskAffinity1Activity2"
+            android:allowTaskReparenting="true"
+            android:launchMode="standard"
+            android:taskAffinity=".t1"/>
+        <activity
+            android:name="android.server.am.intent.Activities$TaskAffinity2Activity"
+            android:allowTaskReparenting="true"
+            android:launchMode="standard"
+            android:taskAffinity=".t2"/>
+        <activity
+            android:name="android.server.am.intent.Activities$TaskAffinity3Activity"
+            android:allowTaskReparenting="true"
+            android:launchMode="standard"
+            android:taskAffinity=".t3"/>
+        <activity
+            android:name="android.server.am.intent.Activities$ClearTaskOnLaunchActivity"
+            android:allowTaskReparenting="true"
+            android:clearTaskOnLaunch="true"
+            android:launchMode="standard"
+            android:taskAffinity=".t2"/>
+        <activity
+            android:name="android.server.am.intent.Activities$DocumentLaunchIntoActivity"
+            android:documentLaunchMode="intoExisting"/>
+        <activity
+            android:name="android.server.am.intent.Activities$DocumentLaunchAlwaysActivity"
+            android:documentLaunchMode="always"/>
+        <activity
+            android:name="android.server.am.intent.Activities$DocumentLaunchNeverActivity"
+            android:documentLaunchMode="never"/>
+        <activity
+            android:name="android.server.am.intent.Activities$NoHistoryActivity"
+            android:noHistory="true"/>
+        <activity
+            android:name="android.server.am.intent.Activities$LauncherActivity"
+            android:documentLaunchMode="always"
+            android:launchMode="singleInstance">
+        </activity>
+
+
     </application>
 
     <instrumentation
diff --git a/tests/framework/base/activitymanager/app/AndroidManifest.xml b/tests/framework/base/activitymanager/app/AndroidManifest.xml
index 475f6f8..be557e0 100755
--- a/tests/framework/base/activitymanager/app/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/app/AndroidManifest.xml
@@ -47,6 +47,10 @@
                 android:resizeableActivity="true"
                 android:exported="true"
         />
+        <activity-alias android:name=".AliasTestActivity"
+                  android:exported="true"
+                  android:targetActivity=".TestActivity"
+        />
         <activity android:name=".ResumeWhilePausingActivity"
                 android:allowEmbedded="true"
                 android:resumeWhilePausing="true"
@@ -179,10 +183,10 @@
                   android:resizeableActivity="true"
                   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
                   android:exported="true">
-                  <layout android:defaultWidth="25%"
-                          android:defaultHeight="35%"
+                  <layout android:defaultWidth="50%"
+                          android:defaultHeight="70%"
                           android:gravity="top|right"
-                          android:minWidth="90dp"
+                          android:minWidth="50dp"
                           android:minHeight="80dp"
                   />
         </activity>
@@ -190,10 +194,10 @@
                   android:resizeableActivity="true"
                   android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
                   android:exported="true">
-                  <layout android:defaultWidth="25%"
-                          android:defaultHeight="35%"
+                  <layout android:defaultWidth="50%"
+                          android:defaultHeight="70%"
                           android:gravity="bottom|left"
-                          android:minWidth="90dp"
+                          android:minWidth="50dp"
                           android:minHeight="80dp"
                   />
         </activity>
@@ -379,6 +383,24 @@
                   android:showWhenLocked="true"
                   android:exported="true" />
 
+        <activity android:name=".InheritShowWhenLockedAddActivity"
+            android:exported="true" />
+
+        <activity android:name=".InheritShowWhenLockedAttrActivity"
+                  android:inheritShowWhenLocked="true"
+                  android:exported="true" />
+
+        <activity android:name=".InheritShowWhenLockedRemoveActivity"
+                  android:inheritShowWhenLocked="true"
+                  android:exported="true" />
+
+        <activity android:name=".NoInheritShowWhenLockedAttrActivity"
+                  android:exported="true" />
+
+        <activity android:name=".ShowWhenLockedAttrImeActivity"
+                  android:showWhenLocked="true"
+                  android:exported="true" />
+
         <activity android:name=".ToastActivity"
                   android:exported="true"/>
 
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
index 05cc88c..e504766 100644
--- a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
@@ -84,10 +84,20 @@
             component("ResumeWhilePausingActivity");
     public static final ComponentName SHOW_WHEN_LOCKED_ACTIVITY =
             component("ShowWhenLockedActivity");
+    public static final ComponentName SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY =
+            component("ShowWhenLockedAttrImeActivity");
     public static final ComponentName SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
             component("ShowWhenLockedAttrActivity");
     public static final ComponentName SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY =
             component("ShowWhenLockedAttrRemoveAttrActivity");
+    public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY =
+            component("InheritShowWhenLockedAddActivity");
+    public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
+            component("InheritShowWhenLockedAttrActivity");
+    public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY =
+            component("InheritShowWhenLockedRemoveActivity");
+    public static final ComponentName NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
+            component("NoInheritShowWhenLockedAttrActivity");
     public static final ComponentName SHOW_WHEN_LOCKED_DIALOG_ACTIVITY =
             component("ShowWhenLockedDialogActivity");
     public static final ComponentName SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY =
@@ -138,6 +148,7 @@
     public static final ComponentName WALLPAPAER_ACTIVITY = component("WallpaperActivity");
     public static final ComponentName LAUNCH_TEST_ON_DESTROY_ACTIVITY = component(
             "LaunchTestOnDestroyActivity");
+    public static final ComponentName ALIAS_TEST_ACTIVITY = component("AliasTestActivity");
 
     public static final ComponentName ASSISTANT_VOICE_INTERACTION_SERVICE =
             component("AssistantVoiceInteractionService");
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java
new file mode 100644
index 0000000..26fdfa0
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class InheritShowWhenLockedAddActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstance) {
+        super.onCreate(savedInstance);
+        setInheritShowWhenLocked(true);
+    }
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java
new file mode 100644
index 0000000..630055c
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+
+public class InheritShowWhenLockedAttrActivity extends Activity {
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java
new file mode 100644
index 0000000..22e65c3
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class InheritShowWhenLockedRemoveActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstance) {
+        super.onCreate(savedInstance);
+        setInheritShowWhenLocked(false);
+    }
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java
new file mode 100644
index 0000000..eaeed61
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+
+public class NoInheritShowWhenLockedAttrActivity extends Activity {
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java
new file mode 100644
index 0000000..7bae38b
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+public class ShowWhenLockedAttrImeActivity extends AbstractLifecycleLogActivity {
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final EditText editText = new EditText(this);
+        final LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+        layout.addView(editText);
+        setContentView(layout);
+
+        getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+        editText.requestFocus();
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json
new file mode 100644
index 0000000..a474887
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json
new file mode 100644
index 0000000..26d5a9c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json
new file mode 100644
index 0000000..8e7fdf1
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json
@@ -0,0 +1,64 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json
new file mode 100644
index 0000000..96e6d50
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json
new file mode 100644
index 0000000..185762f
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_PREVIOUS_IS_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json
new file mode 100644
index 0000000..9e70f30
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json
@@ -0,0 +1,78 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json
new file mode 100644
index 0000000..bd1e268
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_SINGLE_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json
new file mode 100644
index 0000000..eddebc3
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_SINGLE_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json
new file mode 100644
index 0000000..7340ace
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json
new file mode 100644
index 0000000..feac3aa
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json
new file mode 100644
index 0000000..a474887
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json
new file mode 100644
index 0000000..fb393eb
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json
new file mode 100644
index 0000000..20e3d56
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json
new file mode 100644
index 0000000..dfa0aa7
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json
new file mode 100644
index 0000000..c88c21d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json
new file mode 100644
index 0000000..330d7f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json
new file mode 100644
index 0000000..cb92240
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json
new file mode 100644
index 0000000..fac176d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json
new file mode 100644
index 0000000..82fe0fd
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTaskActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$SingleTaskActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json
new file mode 100644
index 0000000..714457e
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json
new file mode 100644
index 0000000..978f3fe
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json
new file mode 100644
index 0000000..00ca419
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json
new file mode 100644
index 0000000..1c7b18b
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json
new file mode 100644
index 0000000..619d6c2a
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json
new file mode 100644
index 0000000..268b07a
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json
@@ -0,0 +1,98 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json
new file mode 100644
index 0000000..5b897d5
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json
@@ -0,0 +1,104 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json
new file mode 100644
index 0000000..0d6973e
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json
@@ -0,0 +1,116 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json
new file mode 100644
index 0000000..330d7f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json
new file mode 100644
index 0000000..4d7984c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json
new file mode 100644
index 0000000..629a371
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json
new file mode 100644
index 0000000..5c57171
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTaskActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$SingleTaskActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json
new file mode 100644
index 0000000..4b330fb
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json
new file mode 100644
index 0000000..c9441032
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTaskActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json
new file mode 100644
index 0000000..03140d2
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json
new file mode 100644
index 0000000..0f4a845
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json
@@ -0,0 +1,84 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json
new file mode 100644
index 0000000..f83daac
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json
new file mode 100644
index 0000000..978f3fe
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json
new file mode 100644
index 0000000..e5edf6b
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json
new file mode 100644
index 0000000..95a867c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json
new file mode 100644
index 0000000..d4052f4
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json
@@ -0,0 +1,58 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$SingleTopActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json
new file mode 100644
index 0000000..e3a826f
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json
@@ -0,0 +1,98 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json
new file mode 100644
index 0000000..6760b49
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json
@@ -0,0 +1,104 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json
new file mode 100644
index 0000000..7f2e4fc
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json
@@ -0,0 +1,108 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json
new file mode 100644
index 0000000..5aff52d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json
@@ -0,0 +1,72 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    },
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json
new file mode 100644
index 0000000..7da81f0
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json
@@ -0,0 +1,68 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": true
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json
new file mode 100644
index 0000000..722814f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json
@@ -0,0 +1,102 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    },
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json
new file mode 100644
index 0000000..126c753
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json
@@ -0,0 +1,86 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            },
+            {
+                "flags": "",
+                "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+                "class": "android.server.am.intent.Activities$RegularActivity",
+                "package": "android.server.cts.am",
+                "startForResult": false
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+                                "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    },
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+                                "state": "STOPPED"
+                            },
+                            {
+                                "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index f1e8616..a696f58 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -47,6 +47,7 @@
 import static android.server.am.Components.TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY;
 import static android.server.am.Components.TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY;
 import static android.server.am.UiDeviceUtils.pressBackButton;
+import static android.server.am.UiDeviceUtils.pressHomeButton;
 import static android.server.am.VirtualDisplayHelper.waitForDefaultDisplayState;
 import static android.view.Display.DEFAULT_DISPLAY;
 
@@ -469,4 +470,58 @@
             assertFalse("Display keeps off", isDisplayOn(DEFAULT_DISPLAY));
         }
     }
+
+    @Test
+    public void testGoingHomeMultipleTimes() throws Exception {
+        for (int i = 0; i < 10; i++) {
+            // Start activity normally
+            launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+            waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY,
+                    "Activity launched on default display must be focused");
+
+            // Press home button
+            launchHomeActivity();
+
+            mAmWmState.assertHomeActivityVisible(true);
+            waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+                    "Activity should become STOPPED");
+            mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+        }
+    }
+
+    @Test
+    public void testPressingHomeButtonMultipleTimes() throws Exception {
+        for (int i = 0; i < 10; i++) {
+            // Start activity normally
+            launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+            waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY,
+                    "Activity launched on default display must be focused");
+
+            // Press home button
+            pressHomeButton();
+
+            // Wait and assert home and activity states
+            mAmWmState.waitForHomeActivityVisible();
+            mAmWmState.assertHomeActivityVisible(true);
+            waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+                    "Activity should become STOPPED");
+            mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+        }
+    }
+
+    @Test
+    public void testPressingHomeButtonMultipleTimesQuick() throws Exception {
+        for (int i = 0; i < 10; i++) {
+            // Start activity normally
+            launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+
+            // Press home button
+            pressHomeButton();
+            mAmWmState.waitForHomeActivityVisible();
+            mAmWmState.assertHomeActivityVisible(true);
+        }
+        waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+                "Activity should become STOPPED");
+        mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+    }
 }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index 9aae800..396e130 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -51,6 +51,7 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
+import static com.android.compatibility.common.util.PackageUtil.supportsRotation;
 
 import android.content.ComponentName;
 import android.content.res.Configuration;
@@ -470,6 +471,10 @@
 
     @Test
     public void testNonFullscreenActivityPermitted() throws Exception {
+        if(!supportsRotation()) {
+            //cannot physically rotate the screen on automotive device, skip
+            return;
+        }
         try (final RotationSession rotationSession = new RotationSession()) {
             rotationSession.set(ROTATION_0);
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
index 5407f62..bc6171a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
@@ -18,6 +18,7 @@
 
 import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.ActivityManagerTestBase.LockScreenSession.FLAG_REMOVE_ACTIVITIES_ON_CLOSE;
 import static android.server.am.Components.DISMISS_KEYGUARD_ACTIVITY;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
 import static android.server.am.Components.TEST_ACTIVITY;
@@ -52,8 +53,8 @@
      */
     @Test
     public void testVirtualDisplayHidesContentWhenLocked() throws Exception {
-        try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
-             final LockScreenSession lockScreenSession = new LockScreenSession()) {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession();
+             final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
             lockScreenSession.setLockCredential();
 
             // Create new usual virtual display.
@@ -84,12 +85,34 @@
     }
 
     /**
+     * Tests that private display cannot show content while device locked.
+     */
+    @Test
+    public void testPrivateDisplayHideContentWhenLocked() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession();
+             final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+            lockScreenSession.setLockCredential();
+
+            final ActivityDisplay newDisplay =
+                    virtualDisplaySession.setPublicDisplay(false).createDisplay();
+            launchActivityOnDisplay(TEST_ACTIVITY, newDisplay.mId);
+
+            lockScreenSession.gotoKeyguard();
+
+            waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+                    "Expected stopped activity on private display");
+            mAmWmState.assertVisibility(TEST_ACTIVITY, false /* visible */);
+        }
+    }
+
+    /**
      * Tests whether a FLAG_DISMISS_KEYGUARD activity on a secondary display dismisses the keyguard.
      */
     @Test
     public void testDismissKeyguard_secondaryDisplay() throws Exception {
-        try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
-             final LockScreenSession lockScreenSession = new LockScreenSession()) {
+        try (final LockScreenSession lockScreenSession =
+                     new LockScreenSession(FLAG_REMOVE_ACTIVITIES_ON_CLOSE);
+             final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
             lockScreenSession.setLockCredential();
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true).
                     createDisplay();
@@ -111,8 +134,9 @@
 
     @Test
     public void testDismissKeyguard_whileOccluded_secondaryDisplay() throws Exception {
-        try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
-             final LockScreenSession lockScreenSession = new LockScreenSession()) {
+        try (final LockScreenSession lockScreenSession =
+                     new LockScreenSession(FLAG_REMOVE_ACTIVITIES_ON_CLOSE);
+             final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
             lockScreenSession.setLockCredential();
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true).
                     createDisplay();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
index fadc8fc..c9044b4 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
@@ -50,8 +50,8 @@
     // Test parameters
     private static final int DEFAULT_WIDTH_DP = 240;
     private static final int DEFAULT_HEIGHT_DP = 160;
-    private static final float DEFAULT_WIDTH_FRACTION = 0.25f;
-    private static final float DEFAULT_HEIGHT_FRACTION = 0.35f;
+    private static final float DEFAULT_WIDTH_FRACTION = 0.50f;
+    private static final float DEFAULT_HEIGHT_FRACTION = 0.70f;
     private static final int MIN_WIDTH_DP = 100;
     private static final int MIN_HEIGHT_DP = 80;
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
index ac73eae..efe401b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
@@ -1493,14 +1493,8 @@
             // Destroy the display and check if activities are removed from system.
         }
 
-        mAmWmState.waitForWithAmState(
-                (state) -> !state.containsActivity(TEST_ACTIVITY)
-                        && !state.containsActivity(RESIZEABLE_ACTIVITY),
-                "Waiting for activity to be removed");
-        mAmWmState.waitForWithWmState(
-                (state) -> !state.containsWindow(getWindowName(TEST_ACTIVITY))
-                        && !state.containsWindow(getWindowName(RESIZEABLE_ACTIVITY)),
-                "Waiting for activity window to be gone");
+        mAmWmState.waitForActivityRemoved(TEST_ACTIVITY);
+        mAmWmState.waitForActivityRemoved(RESIZEABLE_ACTIVITY);
 
         // Check AM state.
         assertFalse("Activity from removed display must be destroyed",
@@ -1546,7 +1540,6 @@
      * Test that the update of display metrics updates all its content.
      */
     @Test
-    @FlakyTest(bugId = 121105810)
     public void testDisplayResize() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
             // Create new virtual display.
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index c5952b3..bb8c144 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -508,6 +508,7 @@
 
         mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
         waitForDockNotMinimized();
+        mAmWmState.waitForActivityRemoved(TEST_ACTIVITY);
         mAmWmState.assertNotExist(TEST_ACTIVITY);
         assertDockNotMinimized();
     }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
new file mode 100644
index 0000000..139c0cd
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
+import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.Components.TEST_ACTIVITY;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.ActivityView;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.FlakyTest;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Build/Install/Run:
+ *      atest CtsActivityManagerDeviceTestCases:ActivityViewTest
+ */
+@Presubmit
+@FlakyTest
+public class ActivityViewTest extends ActivityManagerTestBase {
+
+    private Instrumentation mInstrumentation;
+    private ActivityView mActivityView;
+
+    @Rule
+    public ActivityTestRule<ActivityViewTestActivity> mActivityRule =
+            new ActivityTestRule<>(ActivityViewTestActivity.class);
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        ActivityViewTestActivity activity = mActivityRule.launchActivity(null);
+        mActivityView = activity.getActivityView();
+        separateTestJournal();
+    }
+
+    @Test
+    public void testStartActivity() {
+        launchActivityInActivityView(TEST_ACTIVITY);
+        assertSingleLaunch(TEST_ACTIVITY);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testResizeActivityView() {
+        final int width = 500;
+        final int height = 500;
+
+        launchActivityInActivityView(TEST_ACTIVITY);
+        assertSingleLaunch(TEST_ACTIVITY);
+
+        mActivityView.layout(0, 0, width, height);
+
+        boolean boundsMatched = checkDisplaySize(TEST_ACTIVITY, width, height);
+        assertTrue("displayWidth and displayHeight must equal " + width + "x" + height,
+                boundsMatched);
+    }
+
+    private boolean checkDisplaySize(ComponentName activity, int requestedWidth,
+            int requestedHeight) {
+        final int maxTries = 5;
+        final int retryIntervalMs = 1000;
+
+        boolean boundsMatched = false;
+
+        // Display size for the activity may not get updated right away. Retry in case.
+        for (int i = 0; i < maxTries; i++) {
+            mAmWmState.getWmState().computeState();
+            int displayId = mAmWmState.getAmState().getDisplayByActivity(activity);
+            WindowManagerState.Display display = mAmWmState.getWmState().getDisplay(displayId);
+            int avDisplayWidth = 0;
+            int avDisplayHeight = 0;
+            if (display != null) {
+                Rect bounds = display.mFullConfiguration.windowConfiguration.getAppBounds();
+                if (bounds != null) {
+                    avDisplayWidth = bounds.width();
+                    avDisplayHeight = bounds.height();
+                }
+            }
+            boundsMatched = avDisplayWidth == requestedWidth && avDisplayHeight == requestedHeight;
+            if (boundsMatched) {
+                return true;
+            }
+
+            // wait and try again
+            SystemClock.sleep(retryIntervalMs);
+        }
+
+        return boundsMatched;
+    }
+
+    @Test
+    public void testAppStoppedWithVisibilityGone() {
+        launchActivityInActivityView(TEST_ACTIVITY);
+        assertSingleLaunch(TEST_ACTIVITY);
+
+        separateTestJournal();
+        mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.GONE));
+        mInstrumentation.waitForIdleSync();
+        mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+        assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+    }
+
+    @Test
+    public void testAppStoppedWithVisibilityInvisible() {
+        launchActivityInActivityView(TEST_ACTIVITY);
+        assertSingleLaunch(TEST_ACTIVITY);
+
+        separateTestJournal();
+        mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.INVISIBLE));
+        mInstrumentation.waitForIdleSync();
+        mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+        assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+    }
+
+    @Test
+    public void testAppStopAndStartWithVisibilityChange() {
+        launchActivityInActivityView(TEST_ACTIVITY);
+        assertSingleLaunch(TEST_ACTIVITY);
+
+        separateTestJournal();
+        mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.INVISIBLE));
+        mInstrumentation.waitForIdleSync();
+        mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+        assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+
+        separateTestJournal();
+        mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.VISIBLE));
+        mInstrumentation.waitForIdleSync();
+        mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_RESUMED);
+
+        assertLifecycleCounts(TEST_ACTIVITY, 0, 1, 1, 0, 0, 0, CountSpec.DONT_CARE);
+    }
+
+    private void launchActivityInActivityView(ComponentName activity) {
+        Intent intent = new Intent();
+        intent.setComponent(activity);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        SystemUtil.runWithShellPermissionIdentity(() -> mActivityView.startActivity(intent));
+        mAmWmState.waitForValidState(activity);
+    }
+
+    // Test activity
+    public static class ActivityViewTestActivity extends Activity {
+        private ActivityView mActivityView;
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            mActivityView = new ActivityView(this);
+            setContentView(mActivityView);
+
+            ViewGroup.LayoutParams layoutParams = mActivityView.getLayoutParams();
+            layoutParams.width = MATCH_PARENT;
+            layoutParams.height = MATCH_PARENT;
+            mActivityView.requestLayout();
+        }
+
+        ActivityView getActivityView() {
+            return mActivityView;
+        }
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index 7daccc8..28fe737 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -25,20 +25,40 @@
 import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.Components.PipActivity.EXTRA_SHOW_OVER_KEYGUARD;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
+import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY;
 import static android.server.am.Components.TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY;
 import static android.server.am.UiDeviceUtils.pressBackButton;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
+import android.app.Activity;
 import android.app.KeyguardManager;
 import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import android.support.test.InstrumentationRegistry;
+
+import com.android.cts.mockime.ImeEvent;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:KeyguardLockedTests
@@ -275,6 +295,73 @@
         }
     }
 
+    @Test
+    public void testShowWhenLockedAttrImeActivityAndShowSoftInput() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession();
+             // Leverage MockImeSession to ensure at least an IME exists as default.
+             final MockImeSession mockImeSession = MockImeSession.create(mContext,
+                     InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                     new ImeSettings.Builder())) {
+            lockScreenSession.setLockCredential().gotoKeyguard();
+            mAmWmState.assertKeyguardShowingAndNotOccluded();
+            launchActivity(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
+            mAmWmState.computeState(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY, true);
+
+            // Make sure the activity has been called showSoftInput & IME window is visible.
+            final ImeEventStream stream = mockImeSession.openEventStream();
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+                    TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
+            // Assert the IME is shown on the expected display.
+            mAmWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
+        }
+    }
+
+    @Test
+    public void testShowWhenLockedImeActivityAndShowSoftInput() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession();
+             final TestActivitySession<ShowWhenLockedImeActivity> imeTestActivitySession = new
+                     TestActivitySession<>();
+             // Leverage MockImeSession to ensure at least an IME exists as default.
+             final MockImeSession mockImeSession = MockImeSession.create(mContext,
+                     InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                     new ImeSettings.Builder())) {
+            lockScreenSession.setLockCredential().gotoKeyguard();
+            mAmWmState.assertKeyguardShowingAndNotOccluded();
+            imeTestActivitySession.launchTestActivityOnDisplaySync(ShowWhenLockedImeActivity.class,
+                    DEFAULT_DISPLAY);
+
+            // Make sure the activity has been called showSoftInput & IME window is visible.
+            final ImeEventStream stream = mockImeSession.openEventStream();
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+                    TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
+            // Assert the IME is shown on the expected display.
+            mAmWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
+        }
+    }
+
+    public static class ShowWhenLockedImeActivity extends Activity {
+
+        @Override
+        protected void onCreate(Bundle icicle) {
+            super.onCreate(icicle);
+            final EditText editText = new EditText(this);
+            // Set private IME option for editorMatcher to identify which TextView received
+            // onStartInput event.
+            editText.setPrivateImeOptions(
+                    getClass().getName() + "/" + Long.toString(SystemClock.elapsedRealtimeNanos()));
+            final LinearLayout layout = new LinearLayout(this);
+            layout.setOrientation(LinearLayout.VERTICAL);
+            layout.addView(editText);
+            setContentView(layout);
+
+            // Set showWhenLocked as true & request focus for showing soft input.
+            setShowWhenLocked(true);
+            getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+            editText.requestFocus();
+        }
+    }
+
     /**
      * Waits until the given activity has entered picture-in-picture mode (allowing for the
      * subsequent animation to start).
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index 6ad99cd..f8b4caf 100755
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -23,8 +23,12 @@
 import static android.server.am.Components.BROADCAST_RECEIVER_ACTIVITY;
 import static android.server.am.Components.DISMISS_KEYGUARD_ACTIVITY;
 import static android.server.am.Components.DISMISS_KEYGUARD_METHOD_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY;
 import static android.server.am.Components.KEYGUARD_LOCK_ACTIVITY;
 import static android.server.am.Components.LAUNCHING_ACTIVITY;
+import static android.server.am.Components.NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
 import static android.server.am.Components.SHOW_WHEN_LOCKED_DIALOG_ACTIVITY;
@@ -211,6 +215,101 @@
     }
 
     /**
+     * Tests whether an activity that has called setInheritShowWhenLocked(true) above a
+     * SHOW_WHEN_LOCKED activity is visible if Keyguard is locked.
+     */
+    @Test
+    public void testInheritShowWhenLockedAdd() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            launchActivity(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY);
+            mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY, true);
+
+            lockScreenSession.gotoKeyguard();
+            mAmWmState.computeState(true);
+            mAmWmState.assertKeyguardShowingAndOccluded();
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY, true);
+        }
+    }
+
+    /**
+     * Tests whether an activity that has the manifest attribute inheritShowWhenLocked but then
+     * calls setInheritShowWhenLocked(false) above a SHOW_WHEN_LOCKED activity is invisible if
+     * Keyguard is locked.
+     */
+    @Test
+    public void testInheritShowWhenLockedRemove() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            launchActivity(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY);
+            mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY, true);
+
+            lockScreenSession.gotoKeyguard();
+            mAmWmState.computeState(true);
+            mAmWmState.assertKeyguardShowingAndNotOccluded();
+            assertTrue(mKeyguardManager.isKeyguardLocked());
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY, false);
+        }
+    }
+
+    /**
+     * Tests whether an activity that has the manifest attribute inheritShowWhenLocked above a
+     * SHOW_WHEN_LOCKED activity is visible if Keyguard is locked.
+     * */
+    @Test
+    public void testInheritShowWhenLockedAttr() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            launchActivity(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            lockScreenSession.gotoKeyguard();
+            mAmWmState.computeState(true);
+            mAmWmState.assertKeyguardShowingAndOccluded();
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+        }
+    }
+
+    /**
+     * Tests whether an activity that doesn't have the manifest attribute inheritShowWhenLocked
+     * above a SHOW_WHEN_LOCKED activity is invisible if Keyguard is locked.
+     * */
+    @Test
+    public void testNoInheritShowWhenLocked() throws Exception {
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            launchActivity(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.computeState(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+            lockScreenSession.gotoKeyguard();
+            mAmWmState.computeState(true);
+            mAmWmState.assertKeyguardShowingAndNotOccluded();
+            assertTrue(mKeyguardManager.isKeyguardLocked());
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+            mAmWmState.assertVisibility(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+        }
+    }
+
+    /**
      * Test that when a normal activity finished and an existing FLAG_DISMISS_KEYGUARD activity
      * becomes the top activity, it should be resumed.
      */
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java
new file mode 100644
index 0000000..72b5b0e
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.app.Activity;
+
+/**
+ * A collection of activities with various launch modes used in the intent tests.
+ * Each activity is named after the LaunchMode it has enabled.
+ *
+ * They reflect the activities present in the IntentPlayground app. The IntentPlayground app
+ * resides in development/samples/IntentPlayground
+ */
+public class Activities {
+
+    public static class TrackerActivity extends Activity {
+    }
+
+    public static class RegularActivity extends Activity {
+    }
+
+    public static class SingleTopActivity extends Activity {
+    }
+
+    public static class SingleInstanceActivity extends Activity {
+    }
+
+    public static class SingleInstanceActivity2 extends Activity {
+    }
+
+    public static class SingleTaskActivity extends Activity {
+    }
+
+    public static class SingleTaskActivity2 extends Activity {
+    }
+
+    public static class TaskAffinity1Activity extends Activity {
+    }
+
+    public static class TaskAffinity1Activity2 extends Activity {
+    }
+
+    public static class TaskAffinity2Activity extends Activity {
+    }
+
+    public static class TaskAffinity3Activity extends Activity {
+    }
+
+    public static class ClearTaskOnLaunchActivity extends Activity {
+    }
+
+    public static class DocumentLaunchIntoActivity extends Activity {
+    }
+
+    public static class DocumentLaunchAlwaysActivity extends Activity {
+    }
+
+    public static class DocumentLaunchNeverActivity extends Activity {
+    }
+
+    public static class NoHistoryActivity extends Activity {
+    }
+
+    public static class LauncherActivity extends Activity {
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java
new file mode 100644
index 0000000..cd542e3
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
+import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
+import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
+import static android.server.am.intent.LaunchSequence.intent;
+import static android.server.am.intent.LaunchSequence.intentForResult;
+import static android.server.am.intent.Persistence.flag;
+
+import android.server.am.intent.Activities.RegularActivity;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.LaunchIntent;
+
+import com.google.common.collect.Lists;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains all information to create and reuse intent test launches.
+ * It enumerates all the flags so they can easily be used.
+ *
+ * It also stores commonly used {@link LaunchSequence} objects for reuse.
+ */
+public class Cases {
+
+    public static final IntentFlag CLEAR_TASK = flag(FLAG_ACTIVITY_CLEAR_TASK,
+            "FLAG_ACTIVITY_CLEAR_TASK");
+    public static final IntentFlag CLEAR_TOP = flag(FLAG_ACTIVITY_CLEAR_TOP,
+            "FLAG_ACTIVITY_CLEAR_TOP");
+    private static final IntentFlag SINGLE_TOP = flag(FLAG_ACTIVITY_SINGLE_TOP,
+            "FLAG_ACTIVITY_SINGLE_TOP");
+    public static final IntentFlag NEW_TASK = flag(FLAG_ACTIVITY_NEW_TASK,
+            "FLAG_ACTIVITY_NEW_TASK");
+    public static final IntentFlag NEW_DOCUMENT = flag(FLAG_ACTIVITY_NEW_DOCUMENT,
+            "FLAG_ACTIVITY_NEW_DOCUMENT");
+    private static final IntentFlag MULTIPLE_TASK = flag(FLAG_ACTIVITY_MULTIPLE_TASK,
+            "FLAG_ACTIVITY_MULTIPLE_TASK");
+    public static final IntentFlag RESET_TASK_IF_NEEDED = flag(
+            FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+            "FLAG_ACTIVITY_RESET_TASK_IF_NEEDED");
+    public static final IntentFlag PREVIOUS_IS_TOP = flag(FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+            "FLAG_ACTIVITY_PREVIOUS_IS_TOP");
+    public static final IntentFlag REORDER_TO_FRONT = flag(FLAG_ACTIVITY_REORDER_TO_FRONT,
+            "FLAG_ACTIVITY_REORDER_TO_FRONT");
+
+    // Flag only used for parsing intents that contain no flags.
+    private static final IntentFlag NONE = flag(0, "");
+
+    public final List<IntentFlag> flags = Lists.newArrayList(
+            CLEAR_TASK,
+            CLEAR_TOP,
+            SINGLE_TOP,
+            NEW_TASK,
+            NEW_DOCUMENT,
+            MULTIPLE_TASK,
+            RESET_TASK_IF_NEEDED,
+            PREVIOUS_IS_TOP,
+            REORDER_TO_FRONT
+    );
+
+    // Definition of intents used across multiple test cases.
+    private final LaunchIntent mRegularIntent = intent(RegularActivity.class);
+    private final LaunchIntent mSingleTopIntent = intent(Activities.SingleTopActivity.class);
+    private final LaunchIntent mAff1Intent = intent(Activities.TaskAffinity1Activity.class);
+    private final LaunchIntent mSecondAff1Intent = intent(Activities.TaskAffinity1Activity2.class);
+    private final LaunchIntent mSingleInstanceIntent = intent(
+            Activities.SingleInstanceActivity.class);
+    private final LaunchIntent mSingleTaskIntent = intent(Activities.SingleTaskActivity.class);
+    private final LaunchIntent mRegularForResultIntent = intentForResult(RegularActivity.class);
+
+    // LaunchSequences used across multiple test cases.
+    private final LaunchSequence mRegularSequence = LaunchSequence.create(mRegularIntent);
+
+    // To show that the most recent task get's resumed by new task
+    private final LaunchSequence mTwoAffinitiesSequence =
+            LaunchSequence.create(mAff1Intent)
+                    .append(mRegularIntent)
+                    .append(mAff1Intent.withFlags(NEW_TASK, MULTIPLE_TASK));
+
+    // Used to show that the task affinity is determined by the activity that started it,
+    // Not the affinity of the  current root activity.
+    private final LaunchSequence mRearrangedRootSequence = LaunchSequence.create(mRegularIntent)
+            .append(mAff1Intent.withFlags(NEW_TASK))
+            .append(mRegularIntent)
+            .append(mAff1Intent.withFlags(REORDER_TO_FRONT));
+
+
+    private final LaunchSequence mSingleInstanceActivitySequence =
+            LaunchSequence.create(mSingleInstanceIntent);
+
+    private final LaunchSequence mSingleTaskActivitySequence = LaunchSequence.create(
+            mSingleTaskIntent);
+
+    public List<LaunchSequence> newTaskCases() {
+        LaunchIntent aff1NewTask = mAff1Intent.withFlags(NEW_TASK);
+
+        return Lists.newArrayList(
+                // 1. Single instance will start a new task even without new task set
+                mRegularSequence.act(mSingleInstanceIntent),
+                // 2. With new task it will still end up in a new task
+                mRegularSequence.act(mSingleInstanceIntent.withFlags(NEW_TASK)),
+                // 3. Starting an activity with a different affinity without new task will put it in
+                // the existing task
+                mRegularSequence.act(mAff1Intent),
+                // 4. Starting a task with a different affinity and new task will start a new task
+                mRegularSequence.act(aff1NewTask),
+                // 5. Starting the intent with new task will not add a new activity to the task
+                mRegularSequence.act(mRegularIntent.withFlags(NEW_TASK)),
+                // 6. A different activity with the same affinity will start a new activity in
+                // the sam task
+                mRegularSequence.act(mSingleTopIntent.withFlags(NEW_TASK)),
+                // 7. To show that the most recent task get's resumed by new task, this can't
+                // be observed without differences in the same activity / task
+                mTwoAffinitiesSequence.act(aff1NewTask),
+                // 8. To show that new task respects the root as a single even
+                // if it is not at the bottom
+                mRearrangedRootSequence.act(mAff1Intent.withFlags(NEW_TASK)),
+                // 9. To show that new task with non root does start a new activity.
+                mRearrangedRootSequence.act(mSecondAff1Intent.withFlags(NEW_TASK)),
+                // 10. Multiple task will allow starting activities of the same affinity in
+                // different tasks
+                mRegularSequence.act(mRegularIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+                // 11. Single instance will not start a new task even with multiple task on
+                mSingleInstanceActivitySequence.act(
+                        mSingleInstanceIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+                // 12. The same should happen for single task.
+                mSingleTaskActivitySequence.act(
+                        mSingleTaskIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+                // 13. This starts a regular in a new task
+                mSingleInstanceActivitySequence.act(mRegularIntent),
+                // 14. This adds regular in the same task
+                mSingleTaskActivitySequence.act(mRegularIntent),
+                // 15. Starting the activity for result keeps it in the same task
+                mSingleInstanceActivitySequence.act(mRegularForResultIntent),
+                // 16. Restarts the previous task with regular activity.
+                mRegularSequence.append(mSingleInstanceIntent).act(mRegularIntent)
+        );
+    }
+
+    /**
+     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT }test cases are the same as
+     * {@link Cases#newTaskCases()}, we should check them for differences.
+     */
+    public List<LaunchSequence> newDocumentCases() {
+        LaunchIntent aff1NewDocument = mAff1Intent.withFlags(NEW_DOCUMENT);
+
+        return Lists.newArrayList(
+                // 1. Single instance will start a new task even without new task set
+                mRegularSequence.act(mSingleInstanceIntent),
+                // 2. With new task it will still end up in a new task
+                mRegularSequence.act(mSingleInstanceIntent.withFlags(NEW_DOCUMENT)),
+                // 3. Starting an activity with a different affinity without new task will put it
+                // in the existing task
+                mRegularSequence.act(mAff1Intent),
+                // 4. With new document it will start it's own task
+                mRegularSequence.act(aff1NewDocument),
+                // 5. Starting the intent with new task will not add a new activity to the task
+                mRegularSequence.act(mRegularIntent.withFlags(NEW_DOCUMENT)),
+                // 6. Unlike the case with NEW_TASK, with new Document
+                mRegularSequence.act(mSingleTopIntent.withFlags(NEW_DOCUMENT)),
+                // 7. To show that the most recent task get's resumed by new task
+                mTwoAffinitiesSequence.act(aff1NewDocument),
+                // 8. To show that new task respects the root as a single
+                mRearrangedRootSequence.act(mAff1Intent.withFlags(NEW_DOCUMENT)),
+                // 9. New document starts a third task here, because there was no task for the
+                // document yet
+                mRearrangedRootSequence.act(mSecondAff1Intent.withFlags(NEW_DOCUMENT)),
+                // 10. Multiple task wil allow starting activities of the same affinity in different
+                // tasks
+                mRegularSequence.act(mRegularIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK)),
+                // 11. Single instance will not start a new task even with multiple task on
+                mSingleInstanceActivitySequence
+                        .act(mSingleInstanceIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK)),
+                // 12. The same should happen for single task.
+                mSingleTaskActivitySequence.act(
+                        mSingleTaskIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK))
+        );
+    }
+
+    public List<LaunchSequence> clearCases() {
+        LaunchSequence doubleRegularActivity = mRegularSequence.append(mRegularIntent);
+
+        return Lists.newArrayList(
+                // 1. This will clear the bottom and end up with just one activity
+                mRegularSequence.act(mRegularIntent.withFlags(CLEAR_TOP)),
+                // 2. This will result in still two regulars
+                doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP)),
+                // 3. This will result in a single regular it clears the top regular
+                // activity and then fails to start a new regular activity because it is already
+                // at the root of the task
+                doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, NEW_TASK)),
+                // 3. This will also result in two regulars, showing the first difference between
+                // new document and new task.
+                doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, NEW_DOCUMENT)),
+                // 4. This is here to show that previous is top has no effect on clear top or single
+                // top
+                doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, PREVIOUS_IS_TOP)),
+                // 5. Clear top finds the same activity in the task and clears from there
+                mRegularSequence.append(mAff1Intent).append(mRegularIntent).act(
+                        mAff1Intent.withFlags(CLEAR_TOP))
+        );
+    }
+
+    /**
+     * Tests for {@link android.app.Activity#startActivityForResult()}
+     */
+    //TODO: If b/122968776 is fixed these tests need to be updated
+    public List<LaunchSequence> forResultCases() {
+        LaunchIntent singleTopForResult = intentForResult(Activities.SingleTopActivity.class);
+
+        return Lists.newArrayList(
+                // 1. Start just a single regular activity
+                mRegularSequence.act(mRegularIntent.withFlags(SINGLE_TOP)),
+                // 2. For result will start a second activity
+                mRegularSequence.act(mRegularForResultIntent.withFlags(SINGLE_TOP)),
+                // 3. The same but for SINGLE_TOP as a launch mode
+                LaunchSequence.create(mSingleTopIntent).act(mSingleTopIntent),
+                // 4. Launch mode SINGLE_TOP when launched for result also starts a second activity.
+                LaunchSequence.create(mSingleTopIntent).act(singleTopForResult),
+                // 5. CLEAR_TOP results in a single regular activity
+                mRegularSequence.act(mRegularIntent.withFlags(CLEAR_TOP)),
+                // 6. Clear will still kill the for result
+                mRegularSequence.act(mRegularForResultIntent.withFlags(CLEAR_TOP)),
+                // 7. An activity started for result can go to a different task
+                mRegularSequence.act(mRegularForResultIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+                // 8. Reorder to front with for result
+                mRegularSequence.append(mAff1Intent).act(
+                        mRegularForResultIntent.withFlags(REORDER_TO_FRONT)),
+                // 9. Reorder can move an activity above one that it started for result
+                mRegularSequence.append(intentForResult(Activities.TaskAffinity1Activity.class))
+                        .act(mRegularIntent.withFlags(REORDER_TO_FRONT))
+        );
+    }
+
+    /**
+     * Reset task if needed will trigger when it is delivered with new task set
+     * and there are activities in the task that have a different affinity.
+     *
+     * @return the test cases
+     */
+    //TODO: If b/122324373 is fixed these test need to be updated.
+    public List<LaunchSequence> resetTaskIfNeeded() {
+        // If a task with a different affinity like this get's reset
+        // it will create another task in the same stack with the now orphaned activity.
+        LaunchIntent resetRegularTask = mRegularIntent.withFlags(NEW_TASK,
+                RESET_TASK_IF_NEEDED);
+        LaunchSequence resetIfNeeded = mRegularSequence.append(mAff1Intent)
+                .act(resetRegularTask);
+
+        // If you try to reset a task with an activity that was started for result
+        // it will not move task.
+        LaunchSequence resetWontMoveResult = mRegularSequence.append(
+                intentForResult(Activities.TaskAffinity1Activity.class))
+                .act(resetRegularTask);
+
+        // Reset will not move activities with to a task with that affinity,
+        // instead it will always create a new task in that stack.
+        LaunchSequence resetToExistingTask2 = mRegularSequence
+                .append(mAff1Intent)
+                .append(mAff1Intent.withFlags(NEW_TASK))
+                .act(resetRegularTask);
+
+        // If a reset occurs the activities that move retain the same order
+        // in the new task as they had in the old task.
+        LaunchSequence resetOrdering = mRegularSequence
+                .append(mAff1Intent)
+                .append(mSecondAff1Intent)
+                .act(resetRegularTask);
+
+        return Lists.newArrayList(resetIfNeeded, resetWontMoveResult, resetToExistingTask2,
+                resetOrdering);
+    }
+
+    /**
+     * The human readable flags in the JSON files need to be converted back to the corresponding
+     * IntentFlag object when reading the file. This creates a map from the flags to their
+     * corresponding object.
+     *
+     * @return lookup table for the parsing of intent flags in the json files.
+     */
+    public Map<String, IntentFlag> createFlagParsingTable() {
+        HashMap<String, IntentFlag> flags = new HashMap<>();
+        for (IntentFlag flag : this.flags) {
+            flags.put(flag.name, flag);
+        }
+
+        flags.put(NONE.getName(), NONE);
+        return flags;
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
new file mode 100644
index 0000000..c5daaaa
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Environment;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.TestCase;
+import android.support.test.InstrumentationRegistry;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The {@link IntentGenerationTests#generate()} method runs a very long generation process that
+ * takes over 10 minutes.
+ *
+ * The generated tests and results observed on a reference device can then be used in CTS for
+ * verification.
+ *
+ * It writes a bunch of files out to the directory obtained from
+ * {@link Environment#getExternalStoragePublicDirectory(String)} which is currently
+ * /storage/emulated/0/Documents/.
+ *
+ * These can then be pulled out via adb and put into the intent_tests asset directory.
+ * These are the tests that are checked by atest CtsActivityManagerDeviceTestCases:IntentTests
+ *
+ * Because this process takes so much time, certain timeouts in the AndroidTest.xml need to be
+ * raised.
+ *
+ * <option name="run-command" value="settings put system screen_off_timeout 1200000000" /> in the
+ * target preparer and <option name="test-timeout" value="3600000" /> in the <test class=></test>
+ *
+ * Since this test only exists to trigger this process using the test infrastructure
+ * it is ignored by default.
+ *
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:IntentGenerationTests
+ */
+@Ignore
+public class IntentGenerationTests extends IntentTestBase {
+    private static final Cases CASES = new Cases();
+
+    /**
+     * The flag parsing table used to parse the json files.
+     */
+    private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable();
+
+    /**
+     * Runner used to record testCases.
+     */
+    private LaunchRunner mLaunchRunner;
+
+    /**
+     * The target context we can launch the first activity from.
+     */
+    private Context mTargetContext = InstrumentationRegistry.getTargetContext();
+
+    //20 minute timeout.
+    @Test(timeout = 1_200_000)
+    public void generate() throws Exception {
+        mLaunchRunner.runAndWrite(mTargetContext, "forResult", CASES.forResultCases());
+        mLaunchRunner.runAndWrite(mTargetContext, "newTask", CASES.newTaskCases());
+        mLaunchRunner.runAndWrite(mTargetContext, "newDocumentCases", CASES.newDocumentCases());
+        mLaunchRunner.runAndWrite(mTargetContext, "resetTaskIfNeeded", CASES.resetTaskIfNeeded());
+        mLaunchRunner.runAndWrite(mTargetContext, "clearCases", CASES.clearCases());
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mLaunchRunner = new LaunchRunner(this);
+    }
+
+    /**
+     * Debugging utility to verify a single test in the assets folder.
+     *
+     * @throws IOException   if writing to storage fails
+     * @throws JSONException if the file has invalid json in it.
+     */
+    @Test
+    public void verifySingle() throws IOException, JSONException {
+        String test = "forResult/test-1.json";
+        TestCase testCase = readFromStorage(test);
+        mLaunchRunner.verify(mTargetContext, testCase);
+    }
+
+    private TestCase readFromStorage(String fileName) throws IOException, JSONException {
+        File documentsDirectory = Environment.getExternalStoragePublicDirectory(
+                Environment.DIRECTORY_DOCUMENTS);
+        Path testsFilePath = documentsDirectory.toPath().resolve(fileName);
+
+        JSONObject jsonInTestFile = new JSONObject(
+                new String(Files.readAllBytes(testsFilePath), StandardCharsets.UTF_8));
+        return TestCase.fromJson(jsonInTestFile, TABLE, fileName);
+    }
+
+    /**
+     * This class runs multiple {@link TestCase}-s in a single test.
+     * Therefore the list of componentNames that occur in the test is not known here.
+     *
+     * Instead {@link IntentTestBase#cleanUp(List)} is called from {@link
+     * LaunchRunner#runAndWrite(Context, String, List)} instead.
+     *
+     * @return an emptyList
+     */
+    @Override
+    List<ComponentName> activitiesUsedInTest() {
+        return Collections.emptyList();
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java
new file mode 100644
index 0000000..ded10b7
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.server.am.ActivityManagerTestBase;
+import android.server.am.UiDeviceUtils;
+
+import org.junit.After;
+
+import java.util.List;
+
+public abstract class IntentTestBase extends ActivityManagerTestBase {
+
+    /**
+     * This get's called from {@link IntentGenerationTests} because {@link IntentGenerationTests}
+     * run multiple {@link android.server.am.intent.Persistence.TestCase}-s in a single junit test.
+     *
+     * Normal test classes can just extend this class with manual cleanUp.
+     *
+     * @param activitiesInUsedInTest activities that should be gone after tearDown
+     */
+    public void cleanUp(List<ComponentName> activitiesInUsedInTest) throws Exception {
+        super.tearDown();
+        UiDeviceUtils.pressHomeButton();
+        removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+
+        this.getAmWmState().waitForWithAmState(
+                state -> state.containsNoneOf(activitiesInUsedInTest),
+                "Waiting for activity to be removed");
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        cleanUp(activitiesUsedInTest());
+    }
+
+    /**
+     * @return The activities that are launched in this Test.
+     */
+    abstract List<ComponentName> activitiesUsedInTest();
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
new file mode 100644
index 0000000..e9ff1cb
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.os.Environment;
+import android.server.am.UiDeviceUtils;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.TestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+
+import com.google.common.collect.Lists;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * This test will verify every intent_test json file in a separately run test, through JUnits
+ * Parameterized runner.
+ *
+ * Running a single test using this class is not supported.
+ * For this use case look at {@link IntentGenerationTests#verifySingle()}
+ *
+ * Note: atest CtsActivityManagerDeviceTestCases:IntentTests#verify does not work because the
+ * Parameterized runner won't expose the test that way to atest.
+ *
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:IntentTests
+ */
+@LargeTest
+@RunWith(Parameterized.class)
+public class IntentTests extends IntentTestBase {
+    private static final Cases CASES = new Cases();
+
+    /**
+     * The flag parsing table used to parse the json files.
+     */
+    private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable();
+    private static Context TARGET_CONTEXT = InstrumentationRegistry.getTargetContext();
+
+    private static final int JSON_INDENTATION_LEVEL = 4;
+
+    /**
+     * The runner used to verify the recorded test cases.
+     */
+    private LaunchRunner mLaunchRunner;
+
+    /**
+     * The Test case we are currently verifying.
+     */
+    private TestCase mTestCase;
+
+    public IntentTests(TestCase testCase, String name) {
+        mTestCase = testCase;
+    }
+
+    /**
+     * Read all the tests in the assets of the application and create a separate test to run for
+     * each of them using the {@link org.junit.runners.Parameterized}
+     */
+    @Parameterized.Parameters(name = "{1}")
+    public static Collection<Object[]> data() throws IOException, JSONException {
+        return readAllFromAssets().stream().map(
+                test -> new Object[]{test, test.getName()}).collect(
+                Collectors.toList());
+    }
+
+    @Test
+    public void verify() {
+        mLaunchRunner.verify(TARGET_CONTEXT, mTestCase);
+    }
+
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mLaunchRunner = new LaunchRunner(this);
+    }
+
+    @Override
+    List<ComponentName> activitiesUsedInTest() {
+        return mTestCase.getSetup().componentsInCase();
+    }
+
+    public static List<TestCase> readAllFromAssets() throws IOException, JSONException {
+        List<TestCase> testCases = Lists.newArrayList();
+        AssetManager assets = TARGET_CONTEXT.getAssets();
+
+        List<String> testFiles = Lists.newArrayList();
+        for (String dir : assets.list("")) {
+            for (String file : assets.list(dir)) {
+                if (file.endsWith(".json")) {
+                    testFiles.add(dir + "/" + file);
+                }
+            }
+        }
+
+        for (String testFile : testFiles) {
+            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                    new BufferedInputStream(assets.open(testFile))))) {
+                String jsonData = bufferedReader.lines().collect(
+                        Collectors.joining("\n"));
+
+                TestCase testCase = TestCase.fromJson(
+                        new JSONObject(jsonData), TABLE, testFile);
+
+                testCases.add(testCase);
+            }
+        }
+
+        return testCases;
+    }
+
+    static void writeToDocumentsStorage(TestCase testCase, int number, String dirName)
+            throws JSONException, IOException {
+        File documentsDirectory = Environment.getExternalStoragePublicDirectory(
+                Environment.DIRECTORY_DOCUMENTS);
+        Path testsFilePath = documentsDirectory.toPath().resolve(dirName);
+
+        if (!Files.exists(testsFilePath)) {
+            Files.createDirectories(testsFilePath);
+        }
+        Files.write(testsFilePath.resolve("test-" + number + ".json"),
+                Lists.newArrayList(testCase.toJson().toString(JSON_INDENTATION_LEVEL)));
+    }
+}
+
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
new file mode 100644
index 0000000..5d702db
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static android.server.am.intent.Persistence.LaunchFromIntent.prepareSerialisation;
+import static android.server.am.intent.StateComparisonException.assertEndStatesEqual;
+import static android.server.am.intent.StateComparisonException.assertInitialStateEqual;
+
+import static com.google.common.collect.Iterables.getLast;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.server.am.ActivityAndWindowManagersState;
+import android.server.am.ActivityManagerState;
+import android.server.am.intent.LaunchSequence.LaunchSequenceExecutionInfo;
+import android.server.am.intent.Persistence.GenerationIntent;
+import android.server.am.intent.Persistence.LaunchFromIntent;
+import android.server.am.intent.Persistence.StateDump;
+import android.support.test.InstrumentationRegistry;
+import android.view.Display;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Launch runner is an interpreter for a {@link LaunchSequence} command object.
+ * It supports three main modes of operation.
+ *
+ * 1. The {@link LaunchRunner#runAndWrite} method to run a launch object and write out the
+ * resulting {@link Persistence.TestCase} to device storage
+ *
+ * 2. The {@link LaunchRunner#verify} method to rerun a previously recorded
+ * {@link Persistence.TestCase} and verify that the recorded states match the states resulting from
+ * the rerun.
+ *
+ * 3. The {@link LaunchRunner#run} method to run a launch object and return an {@link LaunchRecord}
+ * that can be used to do assertions directly in the same test.
+ */
+public class LaunchRunner {
+    private static final int ACTIVITY_LAUNCH_TIMEOUT = 10000;
+    private static final int BEFORE_DUMP_TIMEOUT = 3000;
+
+    /**
+     * Used for the waiting utilities.
+     */
+    private IntentTestBase mTestBase;
+
+    /**
+     * The activities that were already present in the system when the test started.
+     * So they can be removed form the outputs, otherwise our tests would be system dependent.
+     */
+    private List<ActivityManagerState.ActivityStack> mBaseStacks;
+
+    public LaunchRunner(IntentTestBase testBase) {
+        mTestBase = testBase;
+        mBaseStacks = getBaseStacks();
+    }
+
+    /**
+     * Re-run a previously recorded {@link Persistence.TestCase} and verify that the recorded
+     * states match the states resulting from the rerun.
+     *
+     * @param initialContext the context to launch the first Activity from.
+     * @param testCase       the {@link Persistence.TestCase} we are verifying.
+     */
+    void verify(Context initialContext, Persistence.TestCase testCase) {
+        List<GenerationIntent> initialState = testCase.getSetup().getInitialIntents();
+        List<GenerationIntent> act = testCase.getSetup().getAct();
+
+        List<Activity> activityLog = Lists.newArrayList();
+
+        // Launch the first activity from the start context
+        GenerationIntent firstIntent = initialState.get(0);
+        activityLog.add(launchFromContext(initialContext, firstIntent.getActualIntent()));
+
+        // launch the rest from the initial intents
+        for (int i = 1; i < initialState.size(); i++) {
+            GenerationIntent generationIntent = initialState.get(i);
+            Activity activityToLaunchFrom = activityLog.get(generationIntent.getLaunchFromIndex(i));
+            Activity result = launch(activityToLaunchFrom, generationIntent.getActualIntent(),
+                    generationIntent.startForResult());
+            activityLog.add(result);
+        }
+
+        // assert that the state after setup is the same this time as the recorded state.
+        StateDump setupStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
+                testCase.getEndState());
+        assertInitialStateEqual(testCase.getInitialState(), setupStateDump);
+
+        // apply all the intents in the act stage
+        for (int i = 0; i < act.size(); i++) {
+            GenerationIntent generationIntent = act.get(i);
+            Activity activityToLaunchFrom = activityLog.get(
+                    generationIntent.getLaunchFromIndex(initialState.size() + i));
+            Activity result = launch(activityToLaunchFrom, generationIntent.getActualIntent(),
+                    generationIntent.startForResult());
+            activityLog.add(result);
+        }
+
+        // assert that the endStates are the same.
+        StateDump endStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
+                testCase.getEndState());
+        assertEndStatesEqual(testCase.getEndState(), endStateDump);
+    }
+
+    /**
+     * Runs a launch object and writes out the resulting {@link Persistence.TestCase} to
+     * device storage
+     *
+     * @param startContext the context to launch the first Activity from.
+     * @param name         the name of the directory to store the json files in.
+     * @param launches     a list of launches to run and record.
+     */
+    public void runAndWrite(Context startContext, String name, List<LaunchSequence> launches)
+            throws Exception {
+        for (int i = 0; i < launches.size(); i++) {
+            Persistence.TestCase testCase = this.runAndSerialize(launches.get(i), startContext,
+                    Integer.toString(i));
+            IntentTests.writeToDocumentsStorage(testCase, i + 1, name);
+            // Cleanup all the activities of this testCase before going to the next
+            // to preserve isolation across test cases.
+            mTestBase.cleanUp(testCase.getSetup().componentsInCase());
+        }
+    }
+
+    private Persistence.TestCase runAndSerialize(LaunchSequence launchSequence,
+            Context startContext, String name) {
+        LaunchRecord launchRecord = run(launchSequence, startContext);
+
+        LaunchSequenceExecutionInfo executionInfo = launchSequence.fold();
+        List<GenerationIntent> setupIntents = prepareSerialisation(executionInfo.setup);
+        List<GenerationIntent> actIntents = prepareSerialisation(executionInfo.acts,
+                setupIntents.size());
+
+        Persistence.Setup setup = new Persistence.Setup(setupIntents, actIntents);
+
+        return new Persistence.TestCase(setup, launchRecord.initialDump, launchRecord.endDump,
+                name);
+    }
+
+    /**
+     * Runs a launch object and returns a {@link LaunchRecord} that can be used to do assertions
+     * directly in the same test.
+     *
+     * @param launch       the {@link LaunchSequence}we want to run
+     * @param startContext the {@link android.content.Context} to launch the first Activity from.
+     * @return {@link LaunchRecord} that can be used to do assertions.
+     */
+    LaunchRecord run(LaunchSequence launch, Context startContext) {
+        LaunchSequence.LaunchSequenceExecutionInfo work = launch.fold();
+        List<Activity> activityLog = Lists.newArrayList();
+
+        if (work.setup.isEmpty() || work.acts.isEmpty()) {
+            throw new IllegalArgumentException("no intents to start");
+        }
+
+        // Launch the first activity from the start context.
+        LaunchFromIntent firstIntent = work.setup.get(0);
+        Activity firstActivity = this.launchFromContext(startContext,
+                firstIntent.getActualIntent());
+
+        activityLog.add(firstActivity);
+
+        // launch the rest from the initial intents.
+        for (int i = 1; i < work.setup.size(); i++) {
+            LaunchFromIntent launchFromIntent = work.setup.get(i);
+            Intent actualIntent = launchFromIntent.getActualIntent();
+            Activity activity = launch(activityLog.get(launchFromIntent.getLaunchFrom()),
+                    actualIntent, launchFromIntent.startForResult());
+            activityLog.add(activity);
+        }
+
+        // record the state after the initial intents.
+        StateDump initialDump = waitDumpAndTrim(getLast(activityLog));
+
+        // apply all the intents in the act stage
+        for (LaunchFromIntent launchFromIntent : work.acts) {
+            Intent actualIntent = launchFromIntent.getActualIntent();
+            Activity activity = launch(activityLog.get(launchFromIntent.getLaunchFrom()),
+                    actualIntent, launchFromIntent.startForResult());
+
+            activityLog.add(activity);
+        }
+
+        //record the end state after all intents are launched.
+        StateDump endDump = waitDumpAndTrim(getLast(activityLog));
+
+        return new LaunchRecord(initialDump, endDump, activityLog);
+    }
+
+    /**
+     * Results from the running of an {@link LaunchSequence} so the user can assert on the results
+     * directly.
+     */
+    class LaunchRecord {
+
+        /**
+         * The end state after the setup intents.
+         */
+        public final StateDump initialDump;
+
+        /**
+         * The end state after the setup and act intents.
+         */
+        public final StateDump endDump;
+
+        /**
+         * The activities that were started by every intent in the {@link LaunchSequence}.
+         */
+        public final List<Activity> mActivitiesLog;
+
+        public LaunchRecord(StateDump initialDump, StateDump endDump,
+                List<Activity> activitiesLog) {
+            this.initialDump = initialDump;
+            this.endDump = endDump;
+            mActivitiesLog = activitiesLog;
+        }
+    }
+
+
+    public Activity launchFromContext(Context context, Intent intent) {
+        Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+                .addMonitor((String) null, null, false);
+
+        context.startActivity(intent);
+        Activity activity = monitor.waitForActivityWithTimeout(ACTIVITY_LAUNCH_TIMEOUT);
+        waitAndAssertActivityLaunched(activity, intent);
+
+        return activity;
+    }
+
+    public Activity launch(Activity activityContext, Intent intent, boolean startForResult) {
+        Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+                .addMonitor((String) null, null, false);
+
+        if (startForResult) {
+            activityContext.startActivityForResult(intent, 1);
+        } else {
+            activityContext.startActivity(intent);
+        }
+        Activity activity = monitor.waitForActivityWithTimeout(ACTIVITY_LAUNCH_TIMEOUT);
+
+        if (activity == null) {
+            return activityContext;
+        } else {
+            waitAndAssertActivityLaunched(activity, intent);
+        }
+
+        return activity;
+    }
+
+    private void waitAndAssertActivityLaunched(Activity activity, Intent intent) {
+        assertNotNull("Intent: " + intent.toString(), activity);
+
+        final ComponentName testActivityName = activity.getComponentName();
+        mTestBase.waitAndAssertTopResumedActivity(testActivityName,
+                Display.DEFAULT_DISPLAY, "Activity must be resumed");
+    }
+
+    /**
+     * After the last activity has been launched we wait for a valid state + an extra three seconds
+     * so have a stable state of the system. Also all previously known stacks in
+     * {@link LaunchRunner#mBaseStacks} is excluded from the output.
+     *
+     * @param activity The last activity to be launched before dumping the state.
+     * @return A stable {@link StateDump}, meaning no more {@link android.app.Activity} is in a
+     * life cycle transition.
+     */
+    public StateDump waitDumpAndTrim(Activity activity) {
+        mTestBase.getAmWmState().waitForValidState(activity.getComponentName());
+        // The last activity that was launched before the dump could still be in an intermediate
+        // lifecycle state. wait an extra 3 seconds for it to settle
+        SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
+        mTestBase.getAmWmState().computeState(activity.getComponentName());
+        List<ActivityManagerState.ActivityStack> endStateStacks =
+                mTestBase.getAmWmState().getAmState().getStacks();
+        return StateDump.fromStacks(endStateStacks, mBaseStacks);
+    }
+
+    /**
+     * Like {@link LaunchRunner#waitDumpAndTrim(Activity)} but also waits until the state becomes
+     * equal to the state we expect. It is therefore only used when verifying a recorded testcase.
+     *
+     * If we take a dump of an unstable state we allow it to settle into the expected state.
+     *
+     * @param activity The last activity to be launched before dumping the state.
+     * @param expected The state that was previously recorded for this testCase.
+     * @return A stable {@link StateDump}, meaning no more {@link android.app.Activity} is in a
+     * life cycle transition.
+     */
+    public StateDump waitDumpAndTrimForVerification(Activity activity, StateDump expected) {
+        mTestBase.getAmWmState().waitForValidState(activity.getComponentName());
+        // The last activity that was launched before the dump could still be in an intermediate
+        // lifecycle state. wait an extra 3 seconds for it to settle
+        SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
+        mTestBase.getAmWmState().waitForWithAmState(
+                am -> StateDump.fromStacks(am.getStacks(), mBaseStacks).equals(expected),
+                "Wait until the activity states match up with what we recorded");
+        mTestBase.getAmWmState().computeState(activity.getComponentName());
+
+        List<ActivityManagerState.ActivityStack> endStateStacks =
+                mTestBase.getAmWmState().getAmState().getStacks();
+
+        return StateDump.fromStacks(endStateStacks, mBaseStacks);
+    }
+
+    private List<ActivityManagerState.ActivityStack> getBaseStacks() {
+        ActivityAndWindowManagersState amWmState = mTestBase.getAmWmState();
+        amWmState.computeState(new ComponentName[]{});
+        return amWmState.getAmState().getStacks();
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
new file mode 100644
index 0000000..8d801e8
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+
+import android.content.ComponentName;
+import android.server.am.intent.Persistence.LaunchFromIntent;
+import android.server.am.intent.Persistence.LaunchIntent;
+import android.support.test.InstrumentationRegistry;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Optional;
+
+
+/**
+ * <pre>
+ * The main API entry point for specifying intent tests.
+ * A {@code Launch} object is an immutable command object to specify sequences of intents to
+ * launch.
+ *
+ * They can be run by a {@link LaunchRunner}
+ * Most tests using this api are defined in {@link Cases}.
+ * The two test classes actually using the tests specified there are:
+ *
+ * 1. {@link IntentGenerationTests}, which runs the cases, records the results and writes them
+ * out to device storage
+ * 2. {@link IntentTests}, which reads the recorded test files and verifies them again.
+ *
+ *
+ * Features supported by this API are:
+ * 1. Starting activities normally or for result.
+ * {@code
+ *  LaunchSequence.start(intentForResult(RegularActivity.class)) // starting an intent for result.
+ *                .append(intent(RegularActivity.class));         // starting an intent normally.
+ * }
+ * 2. Specifying Intent Flags
+ * {@code
+ *   LaunchSequence.start(intent(RegularActivity.class).withFlags(Cases.NEW_TASK));
+ * }
+ *
+ * 3. Launching an intent from any point earlier in the launch sequence.
+ * {@code
+ *   LaunchIntent multipleTask = intent(RegularActivity.class)
+ *                                     .withFlags(Cases.NEW_TASK,Cases.MULTIPLE_TASK);
+ *   LaunchSequence firstTask = LaunchSequence.start(multipleTask);
+ *   firstTask.append(multipleTask).append(intent(SingleTopActivity.class), firstTask);
+ * }
+ *
+ * The above will result in: the first task having two activities in it and the second task having
+ * one activity, instead of the normal behaviour adding only one task.
+ *
+ * It is completely immutable and can therefore be reused without hesitation.
+ * Note that making a launch object doesn't start anything yet until it is ran by a
+ * {@link LaunchRunner}
+ * </pre>
+ */
+public interface LaunchSequence {
+    /**
+     * @return the amount of intents that will launch before this {@link LaunchSequence} object.
+     */
+    int depth();
+
+    /**
+     * Extract all the information that has been built up in this {@link LaunchSequence} object, so
+     * that {@link LaunchRunner} can run the described sequence of intents.
+     */
+    LaunchSequenceExecutionInfo fold();
+
+    /**
+     * @return the {@link LaunchIntent} inside of this {@link LaunchSequence}.
+     */
+    LaunchIntent getIntent();
+
+    /**
+     * Create a {@link LaunchSequence} object this always has
+     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} set because without it we can not
+     * launch from the application context.
+     *
+     * @param intent the first intent to be Launched.
+     * @return an {@link LaunchSequence} object launching just this intent.
+     */
+    static LaunchSequence create(LaunchIntent intent) {
+        return new RootLaunch(intent.withFlags(Cases.NEW_TASK));
+    }
+
+    /**
+     * @param intent the next intent that should be launched
+     * @return a {@link LaunchSequence} that will launch all the intents in this and then
+     * {@code intent}
+     */
+    default LaunchSequence append(LaunchIntent intent) {
+        return new ConsecutiveLaunch(this, intent, false, Optional.empty());
+    }
+
+    /**
+     * @param intent     the next intent that should be launched
+     * @param launchFrom a {@link LaunchSequence} to start the intent from, {@code launchFrom}
+     *                   should be a sub sequence of this.
+     * @return a {@link LaunchSequence} that will launch all the intents in this and then
+     * {@code intent}
+     */
+    default LaunchSequence append(LaunchIntent intent, LaunchSequence launchFrom) {
+        return new ConsecutiveLaunch(this, intent, false, Optional.of(launchFrom));
+    }
+
+    /**
+     * @param intent the intent to Launch
+     * @return a launch with the {@code intent} added to the Act stage.
+     */
+    default LaunchSequence act(LaunchIntent intent) {
+        return new ConsecutiveLaunch(this, intent, true, Optional.empty());
+    }
+
+    /**
+     * @param intent     the intent to Launch
+     * @param launchFrom a {@link LaunchSequence} to start the intent from, {@code launchFrom}
+     *                   should be a sub sequence of this.
+     * @return a launch with the {@code intent} added to the Act stage.
+     */
+    default LaunchSequence act(LaunchIntent intent, LaunchSequence launchFrom) {
+        return new ConsecutiveLaunch(this, intent, true, Optional.of(launchFrom));
+    }
+
+    /**
+     * @param activity the activity to create an intent for.
+     * @return Creates an {@link LaunchIntent} that will target the {@link android.app.activity}
+     * class passed in. see {@link LaunchIntent#withFlags} to add intent flags to the returned
+     * intent.
+     */
+    static LaunchIntent intent(Class<? extends android.app.Activity> activity) {
+        return new LaunchIntent(Lists.newArrayList(), createComponent(activity), false);
+    }
+
+
+    /**
+     * Creates an {@link LaunchIntent} that will be started with {@link
+     * android.app.Activity#startActivityForResult}
+     *
+     * @param activity the activity to create an intent for.
+     */
+    static LaunchIntent intentForResult(Class<? extends android.app.Activity> activity) {
+        return new LaunchIntent(Lists.newArrayList(), createComponent(activity), true);
+    }
+
+    String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
+
+    static ComponentName createComponent(Class<? extends android.app.Activity> activity) {
+        return new ComponentName(packageName, activity.getName());
+    }
+
+    /**
+     * Allows {@link LaunchSequence} objects to form a linkedlist of intents to launch.
+     */
+    class ConsecutiveLaunch implements LaunchSequence {
+        private final LaunchSequence mPrevious;
+        private final LaunchIntent mLaunchIntent;
+        private final boolean mAct;
+
+        public ConsecutiveLaunch(LaunchSequence previous, LaunchIntent launchIntent,
+                boolean act, Optional<LaunchSequence> launchFrom) {
+            mPrevious = previous;
+            mLaunchIntent = launchIntent;
+            mAct = act;
+            mLaunchFrom = launchFrom;
+        }
+
+        /**
+         * This should always be a {@link LaunchSequence} that is in mPrevious.
+         */
+        @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+        private Optional<LaunchSequence> mLaunchFrom;
+
+        @Override
+        public int depth() {
+            return mPrevious.depth() + 1;
+        }
+
+        @Override
+        public LaunchSequenceExecutionInfo fold() {
+            LaunchSequenceExecutionInfo launchSequenceExecutionInfo = mPrevious.fold();
+            int launchSite = mLaunchFrom.map(LaunchSequence::depth).orElse(this.depth() - 1);
+
+            LaunchFromIntent intent = new LaunchFromIntent(mLaunchIntent, launchSite);
+            if (mAct) {
+                launchSequenceExecutionInfo.acts.add(intent);
+            } else {
+                launchSequenceExecutionInfo.setup.add(intent);
+            }
+            return launchSequenceExecutionInfo;
+        }
+
+        @Override
+        public LaunchIntent getIntent() {
+            return mLaunchIntent;
+        }
+    }
+
+    /**
+     * The first intent to launch in a {@link LaunchSequence} Object.
+     */
+    class RootLaunch implements LaunchSequence {
+        /**
+         * The intent that should be launched.
+         */
+        private final LaunchIntent mLaunchIntent;
+
+        public RootLaunch(LaunchIntent launchIntent) {
+            mLaunchIntent = launchIntent;
+        }
+
+        @Override
+        public int depth() {
+            return 0;
+        }
+
+        @Override
+        public LaunchSequenceExecutionInfo fold() {
+            return new LaunchSequenceExecutionInfo(
+                    Lists.newArrayList(new LaunchFromIntent(mLaunchIntent, -1)),
+                    Lists.newArrayList());
+        }
+
+        @Override
+        public LaunchIntent getIntent() {
+            return mLaunchIntent;
+        }
+    }
+
+    /**
+     * Information for the {@link LaunchRunner} to run the launch represented by a {@link
+     * LaunchSequence} object. The {@link LaunchSequence} object is "folded" as a list
+     * into the summary of all intents with the corresponding indexes from what context
+     * to launch them.
+     */
+    class LaunchSequenceExecutionInfo {
+        List<LaunchFromIntent> setup;
+        List<LaunchFromIntent> acts;
+
+        public LaunchSequenceExecutionInfo(List<LaunchFromIntent> setup,
+                List<LaunchFromIntent> acts) {
+            this.setup = setup;
+            this.acts = acts;
+        }
+    }
+}
+
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java
new file mode 100644
index 0000000..e818631
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static java.util.stream.Collectors.toList;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.server.am.ActivityManagerState;
+
+import com.google.common.collect.Lists;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The intent tests are generated by running a series of intents and then recording the end state
+ * of the system. This class contains all the models needed to store the intents that were used to
+ * create the test case and the end states so that they can be asserted on.
+ *
+ * All test cases are serialized to JSON and stored in a single file per testcase.
+ */
+public class Persistence {
+
+    /**
+     * The highest level entity in the JSON file
+     */
+    public static class TestCase {
+        private static final String SETUP_KEY = "setup";
+        private static final String INITIAL_STATE_KEY = "initialState";
+        private static final String END_STATE_KEY = "endState";
+
+        /**
+         * Contains the {@link android.content.Intent}-s that will be launched in this test case.
+         */
+        private final Setup mSetup;
+
+        /**
+         * The state of the system after the {@link Setup#mInitialIntents} have been launched.
+         */
+        private final StateDump mInitialState;
+
+        /**
+         * The state of the system after the {@link Setup#mAct} have been launched
+         */
+        private final StateDump mEndState;
+
+        /**
+         * The name of the testCase, usually the file name it is stored in.
+         * Not actually persisted to json, since it is only used for presentation purposes.
+         */
+        private final String mName;
+
+        public TestCase(Setup setup, StateDump initialState,
+                StateDump endState, String name) {
+            mSetup = setup;
+            mInitialState = initialState;
+            mEndState = endState;
+            mName = name;
+        }
+
+        public JSONObject toJson() throws JSONException {
+            return new JSONObject()
+                    .put(SETUP_KEY, mSetup.toJson())
+                    .put(INITIAL_STATE_KEY, mInitialState.toJson())
+                    .put(END_STATE_KEY, mEndState.toJson());
+        }
+
+        public static TestCase fromJson(JSONObject object,
+                Map<String, IntentFlag> table, String name) throws JSONException {
+            return new TestCase(Setup.fromJson(object.getJSONObject(SETUP_KEY), table),
+                    StateDump.fromJson(object.getJSONObject(INITIAL_STATE_KEY)),
+                    StateDump.fromJson(object.getJSONObject(END_STATE_KEY)), name);
+        }
+
+        public Setup getSetup() {
+            return mSetup;
+        }
+
+        public StateDump getInitialState() {
+            return mInitialState;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public StateDump getEndState() {
+            return mEndState;
+        }
+    }
+
+    /**
+     * Setup consists of two stages. Firstly a list of intents to bring the system in the state we
+     * want to test something in. Secondly a list of intents to bring the system to the final state.
+     */
+    public static class Setup {
+        private static final String INITIAL_INTENT_KEY = "initialIntents";
+        private static final String ACT_KEY = "act";
+        /**
+         * The intent(s) used to bring the system to the initial state.
+         */
+        private final List<GenerationIntent> mInitialIntents;
+
+        /**
+         * The intent(s) that we actually want to test.
+         */
+        private final List<GenerationIntent> mAct;
+
+        public Setup(List<GenerationIntent> initialIntents, List<GenerationIntent> act) {
+            mInitialIntents = initialIntents;
+            mAct = act;
+        }
+
+        public List<ComponentName> componentsInCase() {
+            return Stream.concat(mInitialIntents.stream(), mAct.stream())
+                    .map(GenerationIntent::getActualIntent)
+                    .map(Intent::getComponent)
+                    .collect(Collectors.toList());
+        }
+
+        public JSONObject toJson() throws JSONException {
+            return new JSONObject()
+                    .put(INITIAL_INTENT_KEY, intentsToJson(mInitialIntents))
+                    .put(ACT_KEY, intentsToJson(mAct));
+        }
+
+        public static Setup fromJson(JSONObject object,
+                Map<String, IntentFlag> table) throws JSONException {
+            List<GenerationIntent> initialState = intentsFromJson(
+                    object.getJSONArray(INITIAL_INTENT_KEY), table);
+            List<GenerationIntent> act = intentsFromJson(object.getJSONArray(ACT_KEY), table);
+
+            return new Setup(initialState, act);
+        }
+
+
+        public static JSONArray intentsToJson(List<GenerationIntent> intents)
+                throws JSONException {
+
+            JSONArray intentArray = new JSONArray();
+            for (GenerationIntent intent : intents) {
+                intentArray.put(intent.toJson());
+            }
+            return intentArray;
+        }
+
+        public static List<GenerationIntent> intentsFromJson(JSONArray intentArray,
+                Map<String, IntentFlag> table) throws JSONException {
+            List<GenerationIntent> intents = new ArrayList<>();
+
+            for (int i = 0; i < intentArray.length(); i++) {
+                JSONObject object = (JSONObject) intentArray.get(i);
+                GenerationIntent intent = GenerationIntent.fromJson(object, table);
+
+                intents.add(intent);
+            }
+
+            return intents;
+        }
+
+        public List<GenerationIntent> getInitialIntents() {
+            return mInitialIntents;
+        }
+
+        public List<GenerationIntent> getAct() {
+            return mAct;
+        }
+    }
+
+    /**
+     * An representation of an {@link android.content.Intent} that can be (de)serialized to / from
+     * JSON. It abstracts whether the context it should be started from is implicitly or explicitly
+     * specified.
+     */
+    interface GenerationIntent {
+        Intent getActualIntent();
+
+        JSONObject toJson() throws JSONException;
+
+        int getLaunchFromIndex(int currentPosition);
+
+        boolean startForResult();
+
+        static GenerationIntent fromJson(JSONObject object, Map<String, IntentFlag> table)
+                throws JSONException {
+            if (object.has(LaunchFromIntent.LAUNCH_FROM_KEY)) {
+                return LaunchFromIntent.fromJson(object, table);
+            } else {
+                return LaunchIntent.fromJson(object, table);
+            }
+        }
+    }
+
+    /**
+     * Representation of {@link android.content.Intent} used by the {@link LaunchSequence} api.
+     * It be can used to normally start activities, to start activities for result and Intent Flags
+     * can be added using {@link LaunchIntent#withFlags(IntentFlag...)}
+     */
+    static class LaunchIntent implements GenerationIntent {
+        private static final String FLAGS_KEY = "flags";
+        private static final String PACKAGE_KEY = "package";
+        private static final String CLASS_KEY = "class";
+        private static final String START_FOR_RESULT_KEY = "startForResult";
+
+        private final List<IntentFlag> mIntentFlags;
+        private final ComponentName mComponentName;
+        private final boolean mStartForResult;
+
+        public LaunchIntent(List<IntentFlag> intentFlags, ComponentName componentName,
+                boolean startForResult) {
+            mIntentFlags = intentFlags;
+            mComponentName = componentName;
+            mStartForResult = startForResult;
+        }
+
+        @Override
+        public Intent getActualIntent() {
+            return new Intent().setComponent(mComponentName).setFlags(buildFlag());
+        }
+
+        @Override
+        public int getLaunchFromIndex(int currentPosition) {
+            return currentPosition - 1;
+        }
+
+        @Override
+        public boolean startForResult() {
+            return mStartForResult;
+        }
+
+        public int buildFlag() {
+            int flag = 0;
+            for (IntentFlag intentFlag : mIntentFlags) {
+                flag |= intentFlag.flag;
+            }
+
+            return flag;
+        }
+
+        public String humanReadableFlags() {
+            return mIntentFlags.stream().map(IntentFlag::toString).collect(
+                    Collectors.joining(" | "));
+        }
+
+        public static LaunchIntent fromJson(JSONObject fakeIntent, Map<String, IntentFlag> table)
+                throws JSONException {
+            List<IntentFlag> flags = IntentFlag.parse(table, fakeIntent.getString(FLAGS_KEY));
+
+            boolean startForResult = fakeIntent.optBoolean(START_FOR_RESULT_KEY, false);
+            return new LaunchIntent(flags,
+                    new ComponentName(
+                            fakeIntent.getString(PACKAGE_KEY),
+                            fakeIntent.getString(CLASS_KEY)), startForResult);
+
+        }
+
+        @Override
+        public JSONObject toJson() throws JSONException {
+            return new JSONObject().put(FLAGS_KEY, this.humanReadableFlags())
+                    .put(CLASS_KEY, this.mComponentName.getClassName())
+                    .put(PACKAGE_KEY, this.mComponentName.getPackageName())
+                    .put(START_FOR_RESULT_KEY, mStartForResult);
+        }
+
+        public LaunchIntent withFlags(IntentFlag... flags) {
+            List<IntentFlag> intentFlags = Lists.newArrayList(mIntentFlags);
+            Collections.addAll(intentFlags, flags);
+            return new LaunchIntent(intentFlags, mComponentName, mStartForResult);
+        }
+
+        public List<IntentFlag> getIntentFlags() {
+            return mIntentFlags;
+        }
+
+        public ComponentName getComponentName() {
+            return mComponentName;
+        }
+
+        public boolean isStartForResult() {
+            return mStartForResult;
+        }
+    }
+
+    /**
+     * Representation of {@link android.content.Intent} used by the {@link LaunchSequence} api.
+     * It can used to normally start activities, to start activities for result and Intent Flags
+     * can
+     * be added using {@link LaunchIntent#withFlags(IntentFlag...)} just like {@link LaunchIntent}
+     *
+     * However {@link LaunchFromIntent}  also supports launching from a activity earlier in the
+     * launch sequence. This can be done using {@link LaunchSequence#act} and related methods.
+     */
+    static class LaunchFromIntent implements GenerationIntent {
+        static final String LAUNCH_FROM_KEY = "launchFrom";
+
+        /**
+         * The underlying {@link LaunchIntent} that we are wrapping with the launch point behaviour.
+         */
+        private final LaunchIntent mLaunchIntent;
+
+        /**
+         * The index in the activityLog maintained by {@link LaunchRunner}, used to retrieve the
+         * activity from the log to start this {@link LaunchIntent} from.
+         */
+        private final int mLaunchFrom;
+
+        LaunchFromIntent(LaunchIntent fakeIntent, int launchFrom) {
+            mLaunchIntent = fakeIntent;
+            mLaunchFrom = launchFrom;
+        }
+
+
+        @Override
+        public Intent getActualIntent() {
+            return mLaunchIntent.getActualIntent();
+        }
+
+        @Override
+        public int getLaunchFromIndex(int currentPosition) {
+            return mLaunchFrom;
+        }
+
+        @Override
+        public boolean startForResult() {
+            return mLaunchIntent.mStartForResult;
+        }
+
+        @Override
+        public JSONObject toJson() throws JSONException {
+            return mLaunchIntent.toJson()
+                    .put(LAUNCH_FROM_KEY, mLaunchFrom);
+        }
+
+        public static LaunchFromIntent fromJson(JSONObject object, Map<String, IntentFlag> table)
+                throws JSONException {
+            LaunchIntent fakeIntent = LaunchIntent.fromJson(object, table);
+            int launchFrom = object.optInt(LAUNCH_FROM_KEY, -1);
+
+            return new LaunchFromIntent(fakeIntent, launchFrom);
+        }
+
+        static List<GenerationIntent> prepareSerialisation(List<LaunchFromIntent> intents) {
+            return prepareSerialisation(intents, 0);
+        }
+
+        // In serialized form we only want to store the launch from index if it deviates from the
+        // default, the default being the previous activity.
+        static List<GenerationIntent> prepareSerialisation(List<LaunchFromIntent> intents,
+                int base) {
+            List<GenerationIntent> serializeIntents = Lists.newArrayList();
+            for (int i = 0; i < intents.size(); i++) {
+                LaunchFromIntent launchFromIntent = intents.get(i);
+                serializeIntents.add(launchFromIntent.forget(base + i));
+            }
+
+            return serializeIntents;
+        }
+
+        public GenerationIntent forget(int currentIndex) {
+            if (mLaunchFrom == currentIndex - 1) {
+                return this.mLaunchIntent;
+            } else {
+                return this;
+            }
+        }
+
+        public int getLaunchFrom() {
+            return mLaunchFrom;
+        }
+    }
+
+    /**
+     * An intent flag that also stores the name of the flag.
+     * It is used to be able to put the flags in human readable form in the JSON file.
+     */
+    static class IntentFlag {
+        /**
+         * The underlying flag, should be a value from Intent.FLAG_ACTIVITY_*.
+         */
+        public final int flag;
+        /**
+         * The name of the flag.
+         */
+        public final String name;
+
+        public IntentFlag(int flag, String name) {
+            this.flag = flag;
+            this.name = name;
+        }
+
+        public int getFlag() {
+            return flag;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public int combine(IntentFlag other) {
+            return other.flag | flag;
+        }
+
+        public static List<IntentFlag> parse(Map<String, IntentFlag> names, String flagsToParse) {
+            String[] split = flagsToParse.replaceAll("\\s", "").split("\\|");
+            return Arrays.stream(split).map(names::get).collect(toList());
+        }
+
+        public String toString() {
+            return name;
+        }
+    }
+
+    static IntentFlag flag(int flag, String name) {
+        return new IntentFlag(flag, name);
+    }
+
+    public static class StateDump {
+        final List<StackState> mStacks;
+
+        public static StateDump fromStacks(List<ActivityManagerState.ActivityStack> activityStacks,
+                List<ActivityManagerState.ActivityStack> baseStacks) {
+            List<StackState> stacks = new ArrayList<>();
+            for (ActivityManagerState.ActivityStack stack : trimStacks(activityStacks,
+                    baseStacks)) {
+                stacks.add(new StackState(stack));
+            }
+
+            return new StateDump(stacks);
+        }
+
+        public StateDump(List<StackState> stacks) {
+            mStacks = stacks;
+        }
+
+        JSONObject toJson() throws JSONException {
+            JSONArray stacks = new JSONArray();
+            for (StackState stack : mStacks) {
+                stacks.put(stack.toJson());
+            }
+
+            return new JSONObject().put("stacks", stacks);
+        }
+
+        static StateDump fromJson(JSONObject object) throws JSONException {
+            JSONArray jsonTasks = object.getJSONArray("stacks");
+            List<StackState> stacks = new ArrayList<>();
+
+            for (int i = 0; i < jsonTasks.length(); i++) {
+                stacks.add(StackState.fromJson((JSONObject) jsonTasks.get(i)));
+            }
+
+            return new StateDump(stacks);
+        }
+
+        /**
+         * To make the state dump non device specific we remove every stack that was present
+         * in the system before recording, by their ID. For example a stack containing the launcher
+         * activity.
+         */
+        public static List<ActivityManagerState.ActivityStack> trimStacks(
+                List<ActivityManagerState.ActivityStack> toTrim,
+                List<ActivityManagerState.ActivityStack> trimFrom) {
+
+            for (ActivityManagerState.ActivityStack stack : trimFrom) {
+                toTrim.removeIf(t -> t.getStackId() == stack.getStackId());
+            }
+
+            return toTrim;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            StateDump stateDump = (StateDump) o;
+            return Objects.equals(mStacks, stateDump.mStacks);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mStacks);
+        }
+    }
+
+    /**
+     * A simplified JSON version of the information in {@link ActivityManagerState.ActivityStack}
+     */
+    public static class StackState {
+        private static final String TASKS_KEY = "tasks";
+        private static final String RESUMED_ACTIVITY_KEY = "resumedActivity";
+
+        /**
+         * The component name of the resumedActivity in this Stack, empty string if there is none.
+         */
+        private final String mResumedActivity;
+        /**
+         * The Tasks in this stack ordered from most recent to least recent.
+         */
+        private final List<TaskState> mTasks;
+
+        public StackState(String resumedActivity, List<TaskState> tasks) {
+            mResumedActivity = resumedActivity;
+            mTasks = tasks;
+        }
+
+        public StackState(ActivityManagerState.ActivityStack stack) {
+            this.mResumedActivity = stack.getResumedActivity();
+            mTasks = new ArrayList<>();
+            for (ActivityManagerState.ActivityTask task : stack.getTasks()) {
+                this.mTasks.add(new TaskState(task));
+            }
+        }
+
+        JSONObject toJson() throws JSONException {
+            JSONArray jsonTasks = new JSONArray();
+
+            for (TaskState task : mTasks) {
+                jsonTasks.put(task.toJson());
+            }
+
+            return new JSONObject()
+                    .put(TASKS_KEY, jsonTasks)
+                    .put(RESUMED_ACTIVITY_KEY, mResumedActivity);
+        }
+
+        static StackState fromJson(JSONObject object) throws JSONException {
+            JSONArray jsonTasks = object.getJSONArray(TASKS_KEY);
+            List<TaskState> tasks = new ArrayList<>();
+
+            for (int i = 0; i < jsonTasks.length(); i++) {
+                tasks.add(TaskState.fromJson((JSONObject) jsonTasks.get(i)));
+            }
+
+            return new StackState(object.optString(RESUMED_ACTIVITY_KEY, ""), tasks);
+        }
+
+        public String getResumedActivity() {
+            return mResumedActivity;
+        }
+
+        public List<TaskState> getTasks() {
+            return mTasks;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            StackState stack = (StackState) o;
+            return Objects.equals(mTasks, stack.mTasks);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mResumedActivity, mTasks);
+        }
+    }
+
+    public static class TaskState {
+
+        private static final String ACTIVITIES_KEY = "activities";
+
+        /**
+         * The activities in this task ordered from most recent to least recent.
+         */
+        private List<ActivityState> mActivities = new ArrayList<>();
+
+        public TaskState(List<ActivityState> activities) {
+            mActivities = activities;
+        }
+
+        public TaskState(ActivityManagerState.ActivityTask state) {
+            for (ActivityManagerState.Activity activity : state.getActivities()) {
+                this.mActivities.add(new ActivityState(activity));
+            }
+        }
+
+        JSONObject toJson() throws JSONException {
+            JSONArray jsonActivities = new JSONArray();
+
+            for (ActivityState activity : mActivities) {
+                jsonActivities.put(activity.toJson());
+            }
+
+            return new JSONObject()
+                    .put(ACTIVITIES_KEY, jsonActivities);
+        }
+
+        static TaskState fromJson(JSONObject object) throws JSONException {
+            JSONArray jsonActivities = object.getJSONArray(ACTIVITIES_KEY);
+            List<ActivityState> activities = new ArrayList<>();
+
+            for (int i = 0; i < jsonActivities.length(); i++) {
+                activities.add(ActivityState.fromJson((JSONObject) jsonActivities.get(i)));
+            }
+
+            return new TaskState(activities);
+        }
+
+        public List<ActivityState> getActivities() {
+            return mActivities;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            TaskState task = (TaskState) o;
+            return Objects.equals(mActivities, task.mActivities);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mActivities);
+        }
+    }
+
+    public static class ActivityState {
+        private static final String NAME_KEY = "name";
+        private static final String STATE_KEY = "state";
+        /**
+         * The componentName of this activity.
+         */
+        private final String mComponentName;
+
+        /**
+         * The lifecycle state this activity is in.
+         */
+        private final String mLifeCycleState;
+
+        public ActivityState(String name, String state) {
+            mComponentName = name;
+            mLifeCycleState = state;
+        }
+
+        public ActivityState(ActivityManagerState.Activity activity) {
+            mComponentName = activity.getName();
+            mLifeCycleState = activity.getState();
+        }
+
+
+        JSONObject toJson() throws JSONException {
+            return new JSONObject().put(NAME_KEY, mComponentName).put(STATE_KEY, mLifeCycleState);
+        }
+
+        static ActivityState fromJson(JSONObject object) throws JSONException {
+            return new ActivityState(object.getString(NAME_KEY), object.getString(STATE_KEY));
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            ActivityState activity = (ActivityState) o;
+            return Objects.equals(mComponentName, activity.mComponentName) &&
+                    Objects.equals(mLifeCycleState, activity.mLifeCycleState);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mComponentName, mLifeCycleState);
+        }
+
+        public String getName() {
+            return mComponentName;
+        }
+
+        public String getState() {
+            return mLifeCycleState;
+        }
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java b/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java
new file mode 100644
index 0000000..80a2370
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import org.json.JSONException;
+
+/**
+ * Exception to report differences in the {@link android.server.am.intent.Persistence.StateDump}
+ * when verifying a {@link android.server.am.intent.Persistence.TestCase} using the
+ * {@linkLaunchRunner#verify} method
+ */
+public class StateComparisonException extends RuntimeException {
+    private Persistence.StateDump mExpected;
+    private Persistence.StateDump mActual;
+    private String stage;
+
+    public StateComparisonException(Persistence.StateDump expected,
+            Persistence.StateDump actual, String stage) {
+        mExpected = expected;
+        mActual = actual;
+        this.stage = stage;
+    }
+
+
+    @Override
+    public String getMessage() {
+        try {
+            String newLine = System.lineSeparator();
+            return new StringBuilder()
+                    .append(newLine)
+                    .append(stage)
+                    .append(newLine)
+                    .append("Expected:")
+                    .append(newLine)
+                    .append(mExpected.toJson().toString(2))
+                    .append(newLine)
+                    .append(newLine)
+                    .append("Actual:")
+                    .append(newLine)
+                    .append(mActual.toJson().toString(2))
+                    .append(newLine)
+                    .append(newLine)
+                    .toString();
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return "json parse exception during error message creation";
+        }
+    }
+
+    public static void assertEndStatesEqual(Persistence.StateDump expected,
+            Persistence.StateDump actual) {
+        compareAndThrow(expected, actual, "Different endSates");
+    }
+
+    public static void assertInitialStateEqual(Persistence.StateDump expected,
+            Persistence.StateDump actual) {
+        compareAndThrow(expected, actual, "Different initial states");
+    }
+
+    private static void compareAndThrow(Persistence.StateDump expected,
+            Persistence.StateDump actual, String stage) {
+        if (!expected.equals(actual)) {
+            throw new StateComparisonException(expected, actual, stage);
+        }
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index f76979c..c3be401 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.StateLogger.log;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback
@@ -11,6 +28,7 @@
 
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.app.PictureInPictureParams;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -49,6 +67,9 @@
     final ActivityTestRule mSecondActivityTestRule = new ActivityTestRule(SecondActivity.class,
             true /* initialTouchMode */, false /* launchActivity */);
 
+    final ActivityTestRule mThirdActivityTestRule = new ActivityTestRule(ThirdActivity.class,
+            true /* initialTouchMode */, false /* launchActivity */);
+
     final ActivityTestRule mTranslucentActivityTestRule = new ActivityTestRule(
             TranslucentActivity.class, true /* initialTouchMode */, false /* launchActivity */);
 
@@ -70,6 +91,9 @@
             ConfigChangeHandlingActivity.class, true /* initialTouchMode */,
             false /* launchActivity */);
 
+    final ActivityTestRule mPipActivityTestRule = new ActivityTestRule(
+            PipActivity.class, true /* initialTouchMode */, false /* launchActivity */);
+
     private final ActivityLifecycleMonitor mLifecycleMonitor = ActivityLifecycleMonitorRegistry
             .getInstance();
     private static LifecycleLog mLifecycleLog;
@@ -166,6 +190,10 @@
     public static class SecondActivity extends Activity {
     }
 
+    // Test activity
+    public static class ThirdActivity extends Activity {
+    }
+
     // Translucent test activity
     public static class TranslucentActivity extends Activity {
     }
@@ -251,6 +279,22 @@
     public static class ConfigChangeHandlingActivity extends CallbackTrackingActivity {
     }
 
+    // Pip-capable activity
+    // TODO(b/123013403): Disabled onMultiWindowMode changed callbacks to make the tests pass, so
+    // that they can verify other lifecycle transitions. This should be fixed and switched to
+    // extend CallbackTrackingActivity.
+    public static class PipActivity extends Activity {
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Enter picture in picture with the given aspect ratio if provided
+            if (getIntent().hasExtra(EXTRA_ENTER_PIP)) {
+                enterPictureInPictureMode(new PictureInPictureParams.Builder().build());
+            }
+        }
+    }
+
     static ComponentName getComponentName(Class<? extends Activity> activity) {
         return new ComponentName(InstrumentationRegistry.getContext(), activity);
     }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
new file mode 100644
index 0000000..18b5bfe
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.ActivityManagerState.STATE_PAUSED;
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
+import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.ComponentNameUtils.getWindowName;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.os.Bundle;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Build/Install/Run:
+ *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleFreeformTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecycleFreeformTests extends ActivityLifecycleClientTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        assumeTrue(supportsFreeform());
+    }
+
+    @Test
+    public void testLaunchInFreeform() throws Exception {
+        // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+        mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+        launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Bundle bundle = launchOptions.toBundle();
+
+        // Launch an activity in freeform
+        final Intent firstIntent =
+                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+        // Wait and assert resume
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+                "Activity should be resumed after launch");
+        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                true /* includeCallbacks */);
+    }
+
+    @Test
+    public void testMultiLaunchInFreeform() throws Exception {
+        // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+        mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+        launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Bundle bundle = launchOptions.toBundle();
+
+        // Launch three activities in freeform
+        final Intent firstIntent =
+                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+        final Intent secondIntent =
+                new Intent(InstrumentationRegistry.getContext(), SecondActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(secondIntent, bundle);
+
+        final Intent thirdIntent =
+                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+        // Wait for resume
+        final String message = "Activity should be resumed after launch";
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED, message);
+        waitAndAssertActivityState(getComponentName(SecondActivity.class), STATE_RESUMED, message);
+        waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+        // Assert lifecycle
+        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                true /* includeCallbacks */);
+    }
+
+    @Test
+    public void testLaunchOccludingInFreeform() throws Exception {
+        // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+        mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+        launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Bundle bundle = launchOptions.toBundle();
+
+        // Launch two activities in freeform in the same task
+        final Intent firstIntent =
+                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(new Intent());
+
+        final Intent thirdIntent =
+                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+        // Wait for valid states
+        final String stopMessage = "Activity should be stopped after being covered above";
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_STOPPED,
+                stopMessage);
+        final String message = "Activity should be resumed after launch";
+        waitAndAssertActivityState(getComponentName(SecondActivity.class), STATE_RESUMED, message);
+        waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+        // Assert lifecycle
+        LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                true /* includeCallbacks */);
+
+        // Finish the activity that was occluding the first one
+        getLifecycleLog().clear();
+        secondActivity.finish();
+
+        // Wait and assert the lifecycle
+        mAmWmState.waitForWithAmState(
+                (state) -> !state.containsActivity(getComponentName(SecondActivity.class)),
+                "Waiting for activity to be removed");
+        mAmWmState.waitForWithWmState(
+                (state) -> !state.containsWindow(
+                        getWindowName(getComponentName(SecondActivity.class))),
+                "Waiting for activity window to be gone");
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+                "Activity must be resumed after occluding finished");
+
+        assertFalse("Activity must be destroyed",
+                mAmWmState.getAmState().containsActivity(getComponentName(SecondActivity.class)));
+        assertFalse("Activity must be destroyed",
+                mAmWmState.getWmState().containsWindow(
+                        getWindowName(getComponentName(SecondActivity.class))));
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "finishInOtherStack");
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "finishInOtherStack");
+    }
+
+    @Test
+    public void testLaunchTranslucentInFreeform() throws Exception {
+        // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+        mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+        launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Bundle bundle = launchOptions.toBundle();
+
+        // Launch two activities in freeform in the same task
+        final Intent firstIntent =
+                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+        final Activity transparentActivity = mTranslucentActivityTestRule
+                .launchActivity(new Intent());
+
+        final Intent thirdIntent =
+                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+        // Wait for valid states
+        final String pauseMessage = "Activity should be stopped after transparent launch above";
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_PAUSED,
+                pauseMessage);
+        final String message = "Activity should be resumed after launch";
+        waitAndAssertActivityState(getComponentName(TranslucentActivity.class), STATE_RESUMED,
+                message);
+        waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+        // Assert lifecycle
+        LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                true /* includeCallbacks */);
+
+        // Finish the activity that was occluding the first one
+        getLifecycleLog().clear();
+        transparentActivity.finish();
+
+        // Wait and assert the lifecycle
+        mAmWmState.waitForWithAmState(
+                (state) -> !state.containsActivity(getComponentName(TranslucentActivity.class)),
+                "Waiting for activity to be removed");
+        mAmWmState.waitForWithWmState(
+                (state) -> !state.containsWindow(
+                        getWindowName(getComponentName(TranslucentActivity.class))),
+                "Waiting for activity window to be gone");
+        waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+                "Activity must be resumed after occluding finished");
+
+
+        assertFalse("Activity must be destroyed",
+                mAmWmState.getAmState().containsActivity(
+                        getComponentName(TranslucentActivity.class)));
+        assertFalse("Activity must be destroyed",
+                mAmWmState.getWmState().containsWindow(
+                        getWindowName(getComponentName(TranslucentActivity.class))));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "finishTranslucentOnTop");
+        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+                getLifecycleLog());
+        LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "finishInOtherStack");
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "finishInOtherStack");
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
index 95fc60e..76c712c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -1,5 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
 
 import android.app.Activity;
@@ -11,6 +34,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleKeyguardTests
@@ -34,4 +59,106 @@
             LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
         }
     }
+
+    @Test
+    public void testKeyguardShowHide() throws Exception {
+        if (!supportsSecureLock()) {
+            return;
+        }
+
+        // Launch first activity and wait for resume
+        final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(activity, ON_RESUME));
+
+        // Show and hide lock screen
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            lockScreenSession.setLockCredential().gotoKeyguard();
+            waitAndAssertActivityStates(state(activity, ON_STOP));
+
+            LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
+            getLifecycleLog().clear();
+        } // keyguard hidden
+
+        // Verify that activity was resumed
+        waitAndAssertActivityStates(state(activity, ON_RESUME));
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+    }
+
+    @Test
+    public void testKeyguardShowHideOverSplitScreen() throws Exception {
+        if (!supportsSecureLock() || !supportsSplitScreenMultiWindow()) {
+            return;
+        }
+
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+        // Launch second activity to side
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for second activity to resume.
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+
+        // Show and hide lock screen
+        getLifecycleLog().clear();
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            lockScreenSession.setLockCredential().gotoKeyguard();
+            waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+            waitAndAssertActivityStates(state(secondActivity, ON_STOP));
+
+            LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
+            LifecycleVerifier.assertResumeToStopSequence(SecondActivity.class, getLifecycleLog());
+            getLifecycleLog().clear();
+        } // keyguard hidden
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+                state(secondActivity, ON_RESUME));
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
+    }
+
+    @Test
+    public void testKeyguardShowHideOverPip() throws Exception {
+        if (!supportsPip()) {
+            // Skipping test: no Picture-In-Picture support
+            return;
+        }
+
+        // Launch first activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Clear the log before launching to Pip
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        getLifecycleLog().clear();
+
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        // Wait and assert lifecycle
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+        // Show and hide lock screen
+        getLifecycleLog().clear();
+        try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+            lockScreenSession.setLockCredential().gotoKeyguard();
+            waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+            waitAndAssertActivityStates(state(pipActivity, ON_STOP));
+
+            LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
+            LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                    Arrays.asList(ON_STOP), "keyguardShown");
+            getLifecycleLog().clear();
+        } // keyguard hidden
+
+        // Wait and assert lifecycle
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESTART, ON_START, ON_RESUME, ON_PAUSE), "keyguardGone");
+    }
 }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
new file mode 100644
index 0000000..43cd7d4
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Build/Install/Run:
+ *     atest CtsActivityManagerDeviceTestCases:ActivityLifecyclePipTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecyclePipTests extends ActivityLifecycleClientTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        assumeTrue(supportsPip());
+    }
+
+    @Test
+    public void testGoToPip() throws Exception {
+        // Launch first activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Launch Pip-capable activity
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(new Intent());
+
+        waitAndAssertActivityStates(state(firstActivity, ON_STOP), state(pipActivity, ON_RESUME));
+
+        // Move activity to Picture-In-Picture
+        getLifecycleLog().clear();
+        final ComponentName pipActivityName = getComponentName(PipActivity.class);
+        mAmWmState.computeState(pipActivityName);
+        final int stackId = mAmWmState.getAmState().getStackIdByActivity(pipActivityName);
+        assertNotEquals(stackId, INVALID_STACK_ID);
+        moveTopActivityToPinnedStack(stackId);
+
+        // Wait and assert lifecycle
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE), "enterPip");
+    }
+
+    @Test
+    public void testPipOnLaunch() throws Exception {
+        // Launch first activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Clear the log before launching to Pip
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        getLifecycleLog().clear();
+
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        // Wait and assert lifecycle
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+        final List<LifecycleLog.ActivityCallback> expectedSequence =
+                Arrays.asList(ON_PAUSE, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> extraCycleSequence =
+                Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
+        LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class,
+                getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
+                "activityEnteringPipOnTop");
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
+                "launchAndEnterPip");
+    }
+
+    @Test
+    public void testDestroyPip() throws Exception {
+        // Launch first activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Clear the log before launching to Pip
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        getLifecycleLog().clear();
+
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        // Wait and assert lifecycle
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+        // Exit PiP
+        getLifecycleLog().clear();
+        pipActivity.finish();
+
+        waitAndAssertActivityStates(state(pipActivity, ON_DESTROY));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "finishPip");
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_STOP, ON_DESTROY), "finishPip");
+    }
+
+    @Test
+    public void testLaunchBelowPip() throws Exception {
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+        // Launch a regular activity below
+        getLifecycleLog().clear();
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent()
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait and verify the sequence
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "launchBelowPip");
+    }
+
+    @Test
+    public void testIntoPipSameTask() throws Exception {
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+        // Launch a regular activity into same task
+        getLifecycleLog().clear();
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Wait and verify the sequence
+        waitAndAssertActivityStates(state(pipActivity, ON_STOP), state(firstActivity, ON_PAUSE));
+
+        // TODO(b/123013403): sometimes extra one or even more relaunches happen
+        //final List<LifecycleLog.ActivityCallback> extraDestroySequence =
+        //        Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
+        //                ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+        //waitForActivityTransitions(FirstActivity.class, extraDestroySequence);
+        //final List<LifecycleLog.ActivityCallback> expectedSequence =
+        //        Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+        //LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class, getLifecycleLog(),
+        //        Arrays.asList(extraDestroySequence, expectedSequence),
+        //        "launchIntoPip");
+
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_STOP), "launchIntoPip");
+    }
+
+    @Test
+    public void testDestroyBelowPip() throws Exception {
+        // Launch a regular activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        waitAndAssertActivityStates(state(pipActivity, ON_PAUSE), state(firstActivity, ON_RESUME));
+
+        // Destroy the activity below
+        getLifecycleLog().clear();
+        firstActivity.finish();
+        waitAndAssertActivityStates(state(firstActivity, ON_DESTROY));
+        LifecycleVerifier.assertResumeToDestroySequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "destroyBelowPip");
+    }
+
+    @Test
+    public void testSplitScreenBelowPip() throws Exception {
+        // Launch Pip-capable activity and enter Pip immediately
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+        // Launch first activity
+        getLifecycleLog().clear();
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent()
+                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+
+        // Enter split screen
+        getLifecycleLog().clear();
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                        ON_RESUME, ON_PAUSE), "moveToSplitScreen");
+        // TODO(b/123013403): will fail with callback tracking enabled - delivers extra
+        // MULTI_WINDOW_MODE_CHANGED
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "launchBelow");
+
+        // Launch second activity to side
+        getLifecycleLog().clear();
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for activities to resume and verify lifecycle
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+                false /* includeCallbacks */);
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "launchToSide");
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "launchBelow");
+    }
+
+    @Test
+    public void testPipAboveSplitScreen() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+        // Launch second activity to side
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for activities to resume
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                state(firstActivity, ON_RESUME));
+
+        // Launch Pip-capable activity and enter Pip immediately
+        getLifecycleLog().clear();
+        final Activity pipActivity = mPipActivityTestRule.launchActivity(
+                new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+        // Wait for it to launch and pause. Other activities should not be affected.
+        waitAndAssertActivityStates(state(pipActivity, ON_PAUSE), state(secondActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
+                "launchAndEnterPip");
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "launchPipOnTop");
+        final List<LifecycleLog.ActivityCallback> expectedSequence =
+                Arrays.asList(ON_PAUSE, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> extraCycleSequence =
+                Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
+        // TODO(b/123013403): sometimes extra destroy is observed
+        LifecycleVerifier.assertSequenceMatchesOneOf(SecondActivity.class,
+                getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
+                "activityEnteringPipOnTop");
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
new file mode 100644
index 0000000..1214cf0
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Build/Install/Run:
+ *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleSplitScreenTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecycleSplitScreenTests extends ActivityLifecycleClientTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        assumeTrue(supportsSplitScreenMultiWindow());
+    }
+
+    @Test
+    public void testResumedWhenRecreatedFromInNonFocusedStack() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Launch second activity to stop first
+        final Activity secondActivity =
+                mSecondActivityTestRule.launchActivity(new Intent());
+
+        // Wait for second activity to resume. We must also wait for the first activity to stop
+        // so that this event is not included in the logs.
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                state(firstActivity, ON_STOP));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(secondActivity.getTaskId());
+
+        // CLear logs so we can capture just the destroy sequence
+        getLifecycleLog().clear();
+
+        // Start an activity in separate task (will be placed in secondary stack)
+        getLaunchActivityBuilder().execute();
+
+        // Finish top activity
+        secondActivity.finish();
+
+        waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Verify that the first activity was recreated to resume as it was created before
+        // windowing mode was switched
+        LifecycleVerifier.assertRecreateAndResumeSequence(FirstActivity.class, getLifecycleLog());
+    }
+
+    @Test
+    public void testOccludingMovedBetweenStacks() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+        final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+        mAmWmState.computeState(firstActivityName);
+        int primarySplitStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+        // Launch second activity to side
+        getLifecycleLog().clear();
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for second activity to resume.
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                state(firstActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "launchToSide");
+
+        // Launch third activity on top of second
+        getLifecycleLog().clear();
+        final Activity thirdActivity = mThirdActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+        waitAndAssertActivityStates(state(thirdActivity, ON_RESUME),
+                state(secondActivity, ON_STOP));
+
+        // Move occluding third activity to side, it will occlude first now
+        getLifecycleLog().clear();
+        moveActivityToStack(getComponentName(ThirdActivity.class), primarySplitStack);
+
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                state(firstActivity, ON_STOP));
+        LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "moveToSide");
+        LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE, ON_STOP), "moveToSide");
+    }
+
+    @Test
+    public void testTranslucentMovedBetweenStacks() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+        final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+        mAmWmState.computeState(firstActivityName);
+        int primarySplitStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+        // Launch second activity to side
+        getLifecycleLog().clear();
+        final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for second activity to resume.
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                state(firstActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "launchToSide");
+
+        // Launch translucent activity on top of second
+        getLifecycleLog().clear();
+
+        final Activity translucentActivity = mTranslucentActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        // Second activity should stay resumed, because it's in a separate stack below the
+        // translucent activity.
+        LifecycleVerifier.assertSequence(SecondActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "moveToSide");
+
+        // Move translucent activity to side, it will be on top of the first now
+        getLifecycleLog().clear();
+        moveActivityToStack(getComponentName(TranslucentActivity.class), primarySplitStack);
+
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "moveToSide");
+        LifecycleVerifier.assertSequence(SecondActivity.class, getLifecycleLog(),
+                new ArrayList<>(), "moveToSide");
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE), "moveToSide");
+    }
+
+    @Test
+    public void testResultInNonFocusedStack() throws Exception {
+        // Launch first activity
+        final Activity callbackTrackingActivity =
+                mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        // Wait for first activity to resume
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+
+        // Enter split screen, the activity will be relaunched.
+        getLifecycleLog().clear();
+        moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId(), true /* showRecents */);
+        // Wait for multi-window mode change that will come after activity relaunch and resume.
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_MULTI_WINDOW_MODE_CHANGED));
+        final List<LifecycleLog.ActivityCallback> splitScreenMoveSequence =
+                Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED);
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                splitScreenMoveSequence, "moveToPrimarySplitScreen");
+        getLifecycleLog().clear();
+
+        // Launch second activity
+        // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
+        Instrumentation.ActivityMonitor activityMonitor = InstrumentationRegistry
+                .getInstrumentation()
+                .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
+                        false /* block */);
+
+        callbackTrackingActivity.startActivityForResult(
+                new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
+
+        // Wait for the ActivityMonitor to be hit
+        final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
+                .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
+
+        // Wait for second activity to resume
+        assertNotNull("Second activity should be started", secondActivity);
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+
+        // Verify if the first activity stopped (since it is not currently visible)
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_STOP));
+
+        // Start an activity in separate task (will be placed in secondary stack)
+        final Activity thirdActivity = mThirdActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        // Wait for third activity to resume
+        waitAndAssertActivityStates(state(thirdActivity, ON_RESUME));
+
+        // Finish top activity and verify that activity below became focused.
+        getLifecycleLog().clear();
+        secondActivity.setResult(Activity.RESULT_OK);
+        secondActivity.finish();
+
+        // Check that activity was resumed and result was delivered
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME), "resume");
+    }
+
+    @Test
+    public void testResumedWhenRestartedFromInNonFocusedStack() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Wait for first activity to resume
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Enter split screen
+        getLifecycleLog().clear();
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_RESUME);
+
+        // Launch second activity, first become stopped
+        final Activity secondActivity =
+                mSecondActivityTestRule.launchActivity(new Intent());
+
+        // Wait for second activity to resume and first to stop
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+
+        // Start an activity in separate task (will be placed in secondary stack)
+        final Activity newTaskActivity = mThirdActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        waitAndAssertActivityStates(state(newTaskActivity, ON_RESUME));
+
+        getLifecycleLog().clear();
+
+        // Finish top activity
+        secondActivity.finish();
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+
+        // Verify that the first activity was restarted to resumed state as it was brought back
+        // after windowing mode was switched
+        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+    }
+
+    @Test
+    public void testResumedTranslucentWhenRestartedFromInNonFocusedStack() throws Exception {
+        // Launch first activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Wait for first activity to resume
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
+
+        // Launch a translucent activity, first become paused
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+
+        // Wait for translucent activity to resume and first to pause
+        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+        // Start an activity in separate task (will be placed in secondary stack)
+        final Activity newTaskActivity = mThirdActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+        waitAndAssertActivityStates(state(newTaskActivity, ON_RESUME));
+
+        getLifecycleLog().clear();
+
+        // Finish top activity
+        translucentActivity.finish();
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
+
+        // Verify that the first activity was resumed
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "resume");
+        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+                getLifecycleLog());
+    }
+
+    @Test
+    public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
+        // Launch a singleTop activity
+        final Activity testActivity =
+                mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        // Wait for the activity to resume
+        waitAndAssertActivityStates(state(testActivity, ON_RESUME));
+        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                true /* includeCallbacks */);
+
+        // Enter split screen
+        getLifecycleLog().clear();
+        setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        // Wait for the activity to relaunch
+        final List<LifecycleLog.ActivityCallback> expectedEnterSequence =
+                Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                        ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED);
+        waitForActivityTransitions(CallbackTrackingActivity.class, expectedEnterSequence);
+
+        // Verify that the activity was relaunched and received multi-window mode change
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                expectedEnterSequence, "moveToSplitScreen");
+
+        // Exit split-screen
+        getLifecycleLog().clear();
+        setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
+
+        // Wait for the activity to resume
+        final List<LifecycleLog.ActivityCallback> expectedExitSequence = expectedEnterSequence;
+        waitForActivityTransitions(CallbackTrackingActivity.class, expectedExitSequence);
+
+        // Verify that the activity was relaunched and received multi-window mode change
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                expectedExitSequence, "moveFromSplitScreen");
+    }
+
+    @Test
+    public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
+        // Launch a singleTop activity
+        final Activity testActivity =
+                mConfigChangeHandlingActivityTestRule.launchActivity(new Intent());
+
+        // Wait for the activity to resume
+        waitAndAssertActivityStates(state(testActivity, ON_RESUME));
+        LifecycleVerifier.assertLaunchSequence(ConfigChangeHandlingActivity.class,
+                getLifecycleLog(), true /* includeCallbacks */);
+
+        // Enter split screen
+        getLifecycleLog().clear();
+        setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        // Wait for the activity to receive the change
+        waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED));
+
+        // Verify that the activity was relaunched and received multi-window mode change
+        LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED), "moveToSplitScreen");
+
+        // Exit split-screen
+        getLifecycleLog().clear();
+        setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
+
+        // Wait for the activity to receive the change
+        waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED));
+
+        // Verify that the activity was relaunched and received multi-window mode change
+        LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED), "moveFromSplitScreen");
+    }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index 4d11d47..7698964 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -1,9 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.server.am.ActivityManagerState.STATE_PAUSED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.UiDeviceUtils.pressBackButton;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
@@ -23,11 +41,10 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.fail;
 
 import android.app.Activity;
-import android.app.Instrumentation.ActivityMonitor;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -42,6 +59,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -79,6 +97,192 @@
     }
 
     @Test
+    public void testLaunchTranslucentOnTop() throws Exception {
+        // Launch fullscreen activity
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Launch translucent activity on top
+        getLifecycleLog().clear();
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+                state(translucentActivity, ON_RESUME));
+
+        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+                getLifecycleLog(), true /* launchIsTranslucent */);
+    }
+
+    @Test
+    public void testLaunchDoubleTranslucentOnTop() throws Exception {
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+        // Launch translucent activity on top
+        getLifecycleLog().clear();
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+                state(translucentActivity, ON_RESUME));
+
+        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+                getLifecycleLog(), true /* launchIsTranslucent */);
+
+        // Launch another translucent activity on top
+        getLifecycleLog().clear();
+        final Activity secondTranslucentActivity =
+                mSecondTranslucentActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(translucentActivity, ON_PAUSE),
+                state(secondTranslucentActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE), "launch");
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "launch");
+
+        // Finish top translucent activity
+        getLifecycleLog().clear();
+        secondTranslucentActivity.finish();
+
+        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
+        LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
+                getLifecycleLog());
+        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "launch");
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "launch");
+    }
+
+    @Test
+    public void testTranslucentMovedIntoStack() throws Exception {
+        // Launch a translucent activity and a regular activity in separate stacks
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+                state(translucentActivity, ON_STOP));
+
+        final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+        mAmWmState.computeState(firstActivityName);
+        int firstActivityStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+        // Move translucent activity into the stack with the first activity
+        getLifecycleLog().clear();
+        moveActivityToStack(getComponentName(TranslucentActivity.class), firstActivityStack);
+
+        // Wait for translucent activity to resume and first activity to pause
+        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+                state(firstActivity, ON_PAUSE));
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_PAUSE), "launchOnTop");
+        LifecycleVerifier.assertRestartAndResumeSequence(TranslucentActivity.class,
+                getLifecycleLog());
+    }
+
+    @Test
+    public void testDestroyTopTranslucent() throws Exception {
+        // Launch a regular activity and a a translucent activity in the same stack
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+                state(translucentActivity, ON_RESUME));
+
+        // Finish translucent activity
+        getLifecycleLog().clear();
+        mTranslucentActivityTestRule.finishActivity();
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+                state(translucentActivity, ON_DESTROY));
+
+        // Verify destruction lifecycle
+        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+                getLifecycleLog());
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "resumeAfterTopDestroyed");
+    }
+
+    @Test
+    public void testDestroyOnTopOfTranslucent() throws Exception {
+        // Launch fullscreen activity
+        final Activity firstActivity =
+                mFirstActivityTestRule.launchActivity(new Intent());
+
+        // Launch translucent activity
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+
+        // Launch another fullscreen activity
+        final Activity secondActivity =
+                mSecondActivityTestRule.launchActivity(new Intent());
+
+        // Wait for top activity to resume
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+                occludedActivityState(translucentActivity, secondActivity),
+                occludedActivityState(firstActivity, secondActivity));
+
+        getLifecycleLog().clear();
+
+        final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
+                secondActivity.getWindow().getWindowStyle());
+
+        // Finish top activity
+        mSecondActivityTestRule.finishActivity();
+
+        waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+        if (secondActivityIsTranslucent) {
+            // In this case we don't expect the state of the firstActivity to change since it is
+            // already in the visible paused state. So, we just verify that translucentActivity
+            // transitions to resumed state.
+            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        } else {
+            // Wait for translucent activity to resume
+            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+                    state(firstActivity, ON_START));
+
+            // Verify that the first activity was restarted
+            LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
+        }
+    }
+
+    @Test
+    public void testDestroyDoubleTranslucentOnTop() throws Exception {
+        final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+        final Activity translucentActivity =
+                mTranslucentActivityTestRule.launchActivity(new Intent());
+        final Activity secondTranslucentActivity =
+                mSecondTranslucentActivityTestRule.launchActivity(new Intent());
+        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+                state(translucentActivity, ON_PAUSE), state(secondTranslucentActivity, ON_RESUME));
+
+        // Finish top translucent activity
+        getLifecycleLog().clear();
+        secondTranslucentActivity.finish();
+
+        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
+        LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
+                getLifecycleLog());
+        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "destroy");
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+                "destroy");
+
+        // Finish first translucent activity
+        getLifecycleLog().clear();
+        translucentActivity.finish();
+
+        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+        waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
+        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+                getLifecycleLog());
+        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_RESUME), "secondDestroy");
+    }
+
+    @Test
     public void testLaunchAndDestroy() throws Exception {
         final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
 
@@ -205,212 +409,6 @@
     }
 
     @Test
-    public void testPausedWithTranslucentOnTop() throws Exception {
-        // Launch fullscreen activity
-        final Activity firstActivity =
-                mFirstActivityTestRule.launchActivity(new Intent());
-
-        // Launch translucent activity on top
-        mTranslucentActivityTestRule.launchActivity(new Intent());
-
-        // Launch another translucent activity on top to make sure the fullscreen activity
-        // transitions to final state
-        final Activity secondTranslucentActivity =
-                mSecondTranslucentActivityTestRule.launchActivity(new Intent());
-
-        // Wait for the second translucent activity to become resumed.
-        waitAndAssertActivityStates(state(secondTranslucentActivity, ON_RESUME),
-                state(firstActivity, ON_PAUSE));
-
-        // Assert that the fullscreen activity was not stopped and is in the paused state.
-        LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
-    }
-
-    @Test
-    public void testPausedWhenReturningWithTranslucentOnTop() throws Exception {
-        // Launch fullscreen activity
-        final Activity firstActivity =
-                mFirstActivityTestRule.launchActivity(new Intent());
-
-        // Launch translucent activity
-        final Activity translucentActivity =
-                mTranslucentActivityTestRule.launchActivity(new Intent());
-
-        // Launch another fullscreen activity
-        final Activity secondActivity =
-                mSecondActivityTestRule.launchActivity(new Intent());
-
-        // Wait for top activity to resume
-        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
-                occludedActivityState(translucentActivity, secondActivity),
-                occludedActivityState(firstActivity, secondActivity));
-
-        getLifecycleLog().clear();
-
-        final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
-                secondActivity.getWindow().getWindowStyle());
-
-        // Finish top activity
-        mSecondActivityTestRule.finishActivity();
-
-        if (secondActivityIsTranslucent) {
-            // In this case we don't expect the state of the firstActivity to change since it is
-            // already in the visible paused state. So, we just verify that translucentActivity
-            // transitions to resumed state.
-            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
-        } else {
-            // Wait for translucent activity to resume
-            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
-                    state(firstActivity, ON_START));
-
-            // Verify that the first activity was restarted
-            LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
-        }
-    }
-
-    @Test
-    public void testPausedWhenRecreatedFromInNonFocusedStack() throws Exception {
-        if (!supportsSplitScreenMultiWindow()) {
-            // Skipping test: no split multi-window support
-            return;
-        }
-
-        // Launch first activity
-        final Activity firstActivity =
-                mFirstActivityTestRule.launchActivity(new Intent());
-
-        // Launch second activity to stop first
-        final Activity secondActivity =
-                mSecondActivityTestRule.launchActivity(new Intent());
-
-        // Wait for second activity to resume. We must also wait for the first activity to stop
-        // so that this event is not included in the logs.
-        waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
-                state(firstActivity, ON_STOP));
-
-        // Enter split screen
-        moveTaskToPrimarySplitScreen(secondActivity.getTaskId());
-
-        // CLear logs so we can capture just the destroy sequence
-        getLifecycleLog().clear();
-
-        // Start an activity in separate task (will be placed in secondary stack)
-        getLaunchActivityBuilder().execute();
-
-        // Finish top activity
-        secondActivity.finish();
-
-        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
-
-        // Verify that the first activity was recreated to pause as it was created before
-        // windowing mode was switched
-        LifecycleVerifier.assertRecreateAndPauseSequence(FirstActivity.class, getLifecycleLog());
-    }
-
-    @Test
-    public void testResultInNonFocusedStack() throws Exception {
-        if (!supportsSplitScreenMultiWindow()) {
-            // Skipping test: no split multi-window support
-            return;
-        }
-
-        // Launch first activity
-        final Activity callbackTrackingActivity =
-                mCallbackTrackingActivityTestRule.launchActivity(new Intent());
-
-        // Wait for first activity to resume
-        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
-
-        // Enter split screen
-        moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId(), true /* showRecents */);
-
-        // Launch second activity to pause first
-        // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
-        ActivityMonitor activityMonitor = InstrumentationRegistry.getInstrumentation()
-                .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
-                        false /* block */);
-
-        callbackTrackingActivity.startActivityForResult(
-                new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
-
-        // Wait for the ActivityMonitor to be hit
-        final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
-                .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
-
-        // Wait for second activity to resume
-        assertNotNull("Second activity should be started", secondActivity);
-        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-
-        // Verify if the first activity stopped (since it is not currently visible)
-        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_STOP));
-
-        // Start an activity in separate task (will be placed in secondary stack)
-        getLaunchActivityBuilder().execute();
-
-        waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
-
-        // Finish top activity and verify that activity below became focused.
-        getLifecycleLog().clear();
-        secondActivity.setResult(Activity.RESULT_OK);
-        secondActivity.finish();
-
-        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_START));
-        LifecycleVerifier.assertRestartSequence(CallbackTrackingActivity.class, getLifecycleLog());
-
-        // Bring the first activity to front to verify that it receives the result.
-        getLifecycleLog().clear();
-        final Intent singleTopIntent = new Intent(InstrumentationRegistry.getTargetContext(),
-                CallbackTrackingActivity.class);
-        singleTopIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(singleTopIntent);
-
-        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_ACTIVITY_RESULT, ON_NEW_INTENT, ON_RESUME), "bring to front");
-    }
-
-    @Test
-    public void testPausedWhenRestartedFromInNonFocusedStack() throws Exception {
-        if (!supportsSplitScreenMultiWindow()) {
-            // Skipping test: no split multi-window support
-            return;
-        }
-
-        // Launch first activity
-        final Activity firstActivity =
-                mFirstActivityTestRule.launchActivity(new Intent());
-
-        // Wait for first activity to resume
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-
-        // Enter split screen
-        moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
-
-        // Launch second activity to pause first
-        final Activity secondActivity =
-                mSecondActivityTestRule.launchActivity(new Intent());
-
-        // Wait for second activity to resume
-        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-
-        // Start an activity in separate task (will be placed in secondary stack)
-        getLaunchActivityBuilder().execute();
-
-        waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
-
-        getLifecycleLog().clear();
-
-        // Finish top activity
-        secondActivity.finish();
-
-        waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
-
-        // Verify that the first activity was restarted to pause as it was brought back after
-        // windowing mode was switched
-        LifecycleVerifier.assertRestartAndPauseSequence(FirstActivity.class, getLifecycleLog());
-    }
-
-    @Test
     public void testOnActivityResult() throws Exception {
         final Intent intent = new Intent();
         intent.putExtra(EXTRA_FINISH_IN_ON_RESUME, true);
@@ -425,8 +423,15 @@
         final List<LifecycleLog.ActivityCallback> sequenceWithStop =
                 Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
                         ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> thirdSequence =
+                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                        ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> fourthSequence =
+                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                        ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME);
         LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
-                getLifecycleLog(), Arrays.asList(expectedSequence, sequenceWithStop),
+                getLifecycleLog(),
+                Arrays.asList(expectedSequence, sequenceWithStop, thirdSequence, fourthSequence),
                 "activityResult");
     }
 
@@ -437,19 +442,24 @@
         mLaunchForResultActivityTestRule.launchActivity(intent);
         final boolean isTranslucent = isTranslucent(mLaunchForResultActivityTestRule.getActivity());
 
-        final List<LifecycleLog.ActivityCallback> expectedSequence;
+        final List<List<LifecycleLog.ActivityCallback>> expectedSequences;
         if (isTranslucent) {
-            expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
-                    ON_RESUME, ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME);
+            expectedSequences = Arrays.asList(
+                    Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                            ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME)
+            );
         } else {
-            expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
-                    ON_RESUME, ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START,
-                    ON_RESUME);
+            expectedSequences = Arrays.asList(
+                    Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                            ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME),
+                    Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                            ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME)
+            );
         }
-        waitForActivityTransitions(LaunchForResultActivity.class, expectedSequence);
+        waitForActivityTransitions(LaunchForResultActivity.class, expectedSequences.get(0));
 
-        LifecycleVerifier.assertSequence(LaunchForResultActivity.class,
-                getLifecycleLog(), expectedSequence, "activityResult");
+        LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
+                getLifecycleLog(), expectedSequences, "activityResult");
     }
 
     @Test
@@ -586,7 +596,7 @@
     }
 
     /**
-     * The that recreate request from an activity is executed immediately.
+     * Tests that recreate request from an activity is executed immediately.
      */
     @Test
     public void testLocalRecreate() throws Exception {
@@ -594,36 +604,43 @@
         Activity recreatingActivity = mSingleTopActivityTestRule.launchActivity(new Intent());
 
         // Launch second activity to cover and stop first
-        final LaunchActivityBuilder launchActivityBuilder = getLaunchActivityBuilder();
-        launchActivityBuilder.setNewTask(true).setMultipleTask(true).execute();
+        Activity secondActivity = mSecondActivityTestRule.launchActivity(
+                new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
 
         // Wait for first activity to become stopped
-        waitAndAssertActivityStates(occludedActivityState(recreatingActivity,
-                launchActivityBuilder.isTargetActivityTranslucent()));
+        final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
+                secondActivity.getWindow().getWindowStyle());
+        waitAndAssertActivityStates(
+                occludedActivityState(recreatingActivity, secondActivityIsTranslucent),
+                state(secondActivity, ON_RESUME));
 
         // Launch the activity again to recreate
         getLifecycleLog().clear();
         final Intent intent = new Intent(InstrumentationRegistry.getContext(),
                 SingleTopActivity.class);
         intent.putExtra(EXTRA_RECREATE, true);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for activity to relaunch and resume
-        final List<LifecycleLog.ActivityCallback> expectedRelaunchSequence;
-        if (launchActivityBuilder.isTargetActivityTranslucent()) {
-            expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_STOP,
-                    ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
-                    ON_PAUSE, ON_RESUME);
-        } else {
-            expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME,
+        final List<List<LifecycleLog.ActivityCallback>> expectedRelaunchSequences;
+        if (secondActivityIsTranslucent) {
+            expectedRelaunchSequences = Arrays.asList(Arrays.asList(ON_NEW_INTENT, ON_RESUME,
                     ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                    ON_POST_CREATE, ON_RESUME);
+                    ON_POST_CREATE, ON_RESUME,ON_PAUSE, ON_RESUME));
+        } else {
+            expectedRelaunchSequences = Arrays.asList(
+                    Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_STOP,
+                            ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+                            ON_RESUME),
+                    Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
+                            ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+                            ON_RESUME));
         }
 
-        waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequence);
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                expectedRelaunchSequence, "recreate");
+        waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequences.get(0));
+        LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
+                expectedRelaunchSequences, "recreate");
     }
 
     @Test
@@ -641,7 +658,7 @@
         getLifecycleLog().clear();
         final Intent intent = new Intent(InstrumentationRegistry.getContext(),
                 SingleTopActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for the activity to resume again
@@ -665,7 +682,7 @@
 
         // Launch something on top
         final Intent newTaskIntent = new Intent();
-        newTaskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        newTaskIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
         final Activity secondActivity = mSecondActivityTestRule.launchActivity(newTaskIntent);
 
         // Wait for the activity to resume
@@ -676,7 +693,7 @@
         getLifecycleLog().clear();
         final Intent intent = new Intent(InstrumentationRegistry.getContext(),
                 SingleTopActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for the activity to resume again
@@ -718,7 +735,7 @@
         getLifecycleLog().clear();
         final Intent intent = new Intent(InstrumentationRegistry.getContext(),
                 SingleTopActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for the activity to resume again
@@ -734,91 +751,4 @@
         LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
                 Arrays.asList(expectedSequence, extraPauseSequence), "newIntent");
     }
-
-    @Test
-    public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
-        if (!supportsSplitScreenMultiWindow()) {
-            // Skipping test: no split multi-window support
-            return;
-        }
-
-        // Launch a singleTop activity
-        final Activity testActivity =
-                mCallbackTrackingActivityTestRule.launchActivity(new Intent());
-
-        // Wait for the activity to resume
-        waitAndAssertActivityStates(state(testActivity, ON_RESUME));
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                true /* includeCallbacks */);
-
-        // Enter split screen
-        getLifecycleLog().clear();
-        setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY,
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-
-        // Wait for the activity to pause
-        final List<LifecycleLog.ActivityCallback> expectedEnterSequence =
-                Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                        ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED, ON_PAUSE);
-        waitForActivityTransitions(CallbackTrackingActivity.class, expectedEnterSequence);
-
-        // Verify that the activity was relaunched and received multi-window mode change
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                expectedEnterSequence, "moveToSplitScreen");
-
-        // Exit split-screen
-        getLifecycleLog().clear();
-        setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
-
-        // Wait for the activity to resume
-        final List<LifecycleLog.ActivityCallback> expectedExitSequence =
-                Arrays.asList(ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                        ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_MULTI_WINDOW_MODE_CHANGED,
-                        ON_RESUME);
-        waitForActivityTransitions(CallbackTrackingActivity.class, expectedExitSequence);
-
-        // Verify that the activity was relaunched and received multi-window mode change
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                expectedExitSequence, "moveFromSplitScreen");
-    }
-
-    @Test
-    public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
-        if (!supportsSplitScreenMultiWindow()) {
-            // Skipping test: no split multi-window support
-            return;
-        }
-
-        // Launch a singleTop activity
-        final Activity testActivity =
-                mConfigChangeHandlingActivityTestRule.launchActivity(new Intent());
-
-        // Wait for the activity to resume
-        waitAndAssertActivityStates(state(testActivity, ON_RESUME));
-        LifecycleVerifier.assertLaunchSequence(ConfigChangeHandlingActivity.class,
-                getLifecycleLog(), true /* includeCallbacks */);
-
-        // Enter split screen
-        getLifecycleLog().clear();
-        setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY,
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-
-        // Wait for the activity to pause
-        waitAndAssertActivityStates(state(testActivity, ON_PAUSE));
-
-        // Verify that the activity was relaunched and received multi-window mode change
-        LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_PAUSE), "moveToSplitScreen");
-
-        // Exit split-screen
-        getLifecycleLog().clear();
-        setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
-
-        // Wait for the activity to resume
-        waitAndAssertActivityStates(state(testActivity, ON_RESUME));
-
-        // Verify that the activity was relaunched and received multi-window mode change
-        LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_RESUME), "moveFromSplitScreen");
-    }
 }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
index ef31add..e6aa995 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
@@ -16,14 +16,6 @@
 
 package android.server.am.lifecycle;
 
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.server.am.ActivityLauncher;
-import android.support.test.InstrumentationRegistry;
-import org.junit.Test;
-
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
@@ -32,11 +24,22 @@
 import static android.server.am.ActivityManagerState.STATE_DESTROYED;
 import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ComponentNameUtils.getActivityName;
+import static android.server.am.Components.ALIAS_TEST_ACTIVITY;
+import static android.server.am.Components.TEST_ACTIVITY;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.server.am.ActivityLauncher;
+
+import org.junit.Test;
+
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityStarterTests
@@ -234,6 +237,38 @@
     }
 
     /**
+     * Tests that the existing task would be brought to top while launching alias activity or
+     * real activity without creating new activity instances, tasks, or stacks.
+     */
+    @Test
+    public void testLaunchAliasActivity() {
+        // Launch alias activity.
+        getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(ALIAS_TEST_ACTIVITY)
+                .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+        final int stacks = mAmWmState.getAmState().getStackCounts();
+        final int taskId =
+                mAmWmState.getAmState().getTaskByActivity(ALIAS_TEST_ACTIVITY).getTaskId();
+
+        // Return to home and launch the alias activity again.
+        launchHomeActivity();
+        getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(ALIAS_TEST_ACTIVITY)
+                .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+        assertEquals("Instance of the activity in its task must be only one", 1,
+                mAmWmState.getAmState().getActivityCountInTask(taskId, ALIAS_TEST_ACTIVITY));
+        assertEquals("Stacks counts should not be increased.", stacks,
+                mAmWmState.getAmState().getStackCounts());
+
+        // Return to home and launch the real activity.
+        launchHomeActivity();
+        getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(TEST_ACTIVITY)
+                .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+        assertEquals("Instance of the activity in its task must be only one", 1,
+                mAmWmState.getAmState().getActivityCountInTask(taskId, ALIAS_TEST_ACTIVITY));
+        assertEquals("Stacks counts should not be increased.", stacks,
+                mAmWmState.getAmState().getStackCounts());
+    }
+
+    /**
      * This test case tests behavior of activities launched with FLAG_ACTIVITY_NEW_TASK
      * and FLAG_ACTIVITY_CLEAR_TASK.
      * A first launched activity is finished, then a second activity is created if the
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
index da8296c..6018f43 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
 import static android.server.am.StateLogger.log;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
index 24b384b..25374e5 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
 import static org.junit.Assert.fail;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
index 8c87439..35cb0bc 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
 package android.server.am.lifecycle;
 
 import static android.server.am.StateLogger.log;
@@ -31,10 +47,14 @@
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch");
 
-        final List<ActivityCallback> expectedTransitions = includeCallbacks
+        final List<ActivityCallback> expectedTransitions = getLaunchSequence(includeCallbacks);
+        assertEquals(errorMessage, expectedTransitions, observedTransitions);
+    }
+
+    static List<ActivityCallback> getLaunchSequence(boolean includeCallbacks) {
+        return includeCallbacks
                 ? Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME)
                 : Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
-        assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
     static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
@@ -101,7 +121,7 @@
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
-    static void assertRestartAndPauseSequence(Class<? extends Activity> activityClass,
+    static void assertRestartAndResumeSequence(Class<? extends Activity> activityClass,
                                               LifecycleLog lifecycleLog) {
         final List<ActivityCallback> observedTransitions =
                 lifecycleLog.getActivityLog(activityClass);
@@ -109,11 +129,11 @@
         final String errorMessage = errorDuringTransition(activityClass, "restart and pause");
 
         final List<ActivityCallback> expectedTransitions =
-                Arrays.asList(ON_RESTART, ON_START, ON_RESUME, ON_PAUSE);
+                Arrays.asList(ON_RESTART, ON_START, ON_RESUME);
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
-    static void assertRecreateAndPauseSequence(Class<? extends Activity> activityClass,
+    static void assertRecreateAndResumeSequence(Class<? extends Activity> activityClass,
                                               LifecycleLog lifecycleLog) {
         final List<ActivityCallback> observedTransitions =
                 lifecycleLog.getActivityLog(activityClass);
@@ -121,7 +141,7 @@
         final String errorMessage = errorDuringTransition(activityClass, "recreateA  and pause");
 
         final List<ActivityCallback> expectedTransitions =
-                Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+                Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
@@ -137,6 +157,29 @@
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
+    static void assertResumeToDestroySequence(Class<? extends Activity> activityClass,
+            LifecycleLog lifecycleLog) {
+        final List<ActivityCallback> observedTransitions =
+                lifecycleLog.getActivityLog(activityClass);
+        log("Observed sequence: " + observedTransitions);
+        final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
+
+        final List<ActivityCallback> expectedTransitions = Arrays.asList(ON_PAUSE, ON_STOP,
+                ON_DESTROY);
+        assertEquals(errorMessage, expectedTransitions, observedTransitions);
+    }
+
+    static void assertResumeToStopSequence(Class<? extends Activity> activityClass,
+            LifecycleLog lifecycleLog) {
+        final List<ActivityCallback> observedTransitions =
+                lifecycleLog.getActivityLog(activityClass);
+        log("Observed sequence: " + observedTransitions);
+        final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
+
+        final List<ActivityCallback> expectedTransitions = Arrays.asList(ON_PAUSE, ON_STOP);
+        assertEquals(errorMessage, expectedTransitions, observedTransitions);
+    }
+
     static void assertRelaunchSequence(Class<? extends Activity> activityClass,
             LifecycleLog lifecycleLog, ActivityCallback startState) {
         final List<ActivityCallback> expectedTransitions;
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
index 7671bab..80cf75a 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
@@ -306,6 +306,13 @@
                 "***Waiting for Activity State: " + activityState);
     }
 
+    public void waitForActivityRemoved(ComponentName activityName) {
+        waitForWithAmState((state) -> !state.containsActivity(activityName),
+                "Waiting for activity to be removed");
+        waitForWithWmState((state) -> !state.containsWindow(getWindowName(activityName)),
+                "Waiting for activity window to be gone");
+    }
+
     @Deprecated
     void waitForFocusedStack(int stackId) {
         waitForWithAmState(state -> state.getFocusedStackId() == stackId,
@@ -343,11 +350,11 @@
         assertNotNull(ws);
     }
 
-    void waitForWithAmState(Predicate<ActivityManagerState> waitCondition, String message) {
+    public void waitForWithAmState(Predicate<ActivityManagerState> waitCondition, String message) {
         waitFor((amState, wmState) -> waitCondition.test(amState), message);
     }
 
-    void waitForWithWmState(Predicate<WindowManagerState> waitCondition, String message) {
+    public void waitForWithWmState(Predicate<WindowManagerState> waitCondition, String message) {
         waitFor((amState, wmState) -> waitCondition.test(wmState), message);
     }
 
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
index db59381..40ce779a 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
@@ -32,7 +32,9 @@
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
+
 import androidx.annotation.Nullable;
+
 import android.util.SparseArray;
 
 import com.android.server.am.nano.ActivityDisplayProto;
@@ -364,7 +366,7 @@
         return new ArrayList<>(mDisplays);
     }
 
-    List<ActivityStack> getStacks() {
+    public List<ActivityStack> getStacks() {
         return new ArrayList<>(mStacks);
     }
 
@@ -376,7 +378,7 @@
         return mDisplays.size();
     }
 
-    boolean containsActivity(ComponentName activityName) {
+    public boolean containsActivity(ComponentName activityName) {
         final String fullName = getActivityName(activityName);
         for (ActivityStack stack : mStacks) {
             for (ActivityTask task : stack.mTasks) {
@@ -390,6 +392,24 @@
         return false;
     }
 
+    public boolean containsNoneOf(Iterable<ComponentName> activityNames) {
+        for (ComponentName activityName : activityNames) {
+            String fullName = getActivityName(activityName);
+
+            for (ActivityStack stack : mStacks) {
+                for (ActivityTask task : stack.mTasks) {
+                    for (Activity activity : task.mActivities) {
+                        if (activity.name.equals(fullName)) {
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
     boolean containsActivityInWindowingMode(ComponentName activityName, int windowingMode) {
         final String fullName = getActivityName(activityName);
         for (ActivityStack stack : mStacks) {
@@ -598,11 +618,15 @@
         return 0;
     }
 
+    public int getStackCounts() {
+        return mStacks.size();
+    }
+
     boolean pendingActivityContain(ComponentName activityName) {
         return mPendingActivities.contains(getActivityName(activityName));
     }
 
-    static class ActivityDisplay extends ActivityContainer {
+    public static class ActivityDisplay extends ActivityContainer {
 
         int mId;
         ArrayList<ActivityStack> mStacks = new ArrayList<>();
@@ -643,9 +667,13 @@
             }
             return false;
         }
+        
+        public ArrayList<ActivityStack> getStacks() {
+            return mStacks;
+        }
     }
 
-    static class ActivityStack extends ActivityContainer {
+    public static class ActivityStack extends ActivityContainer {
 
         int mDisplayId;
         int mStackId;
@@ -690,7 +718,7 @@
             return null;
         }
 
-        List<ActivityTask> getTasks() {
+        public List<ActivityTask> getTasks() {
             return new ArrayList<>(mTasks);
         }
 
@@ -702,6 +730,14 @@
             }
             return null;
         }
+
+        public int getStackId() {
+            return mStackId;
+        }
+
+        public String getResumedActivity() {
+            return mResumedActivity;
+        }
     }
 
     public static class ActivityTask extends ActivityContainer {
@@ -740,6 +776,10 @@
         public int getTaskId() {
             return mTaskId;
         }
+
+        public ArrayList<Activity> getActivities() {
+            return mActivities;
+        }
     }
 
     public static class Activity extends ActivityContainer {
@@ -762,6 +802,14 @@
             }
             translucent = proto.translucent;
         }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getState() {
+            return state;
+        }
     }
 
     static abstract class ActivityContainer extends WindowManagerState.ConfigurationContainer {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 7303027..a5351b8c 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -85,6 +85,7 @@
 import static android.support.test.InstrumentationRegistry.getContext;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Surface.ROTATION_0;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -99,15 +100,19 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.server.am.CommandSession.ActivityCallback;
@@ -171,11 +176,13 @@
     private static final String SECOND_TEST_PACKAGE = "android.server.am.second";
     private static final String THIRD_TEST_PACKAGE = "android.server.am.third";
     private static final List<String> TEST_PACKAGES;
+
     static {
         final List<String> testPackages = new ArrayList<>(3);
         testPackages.add(TEST_PACKAGE);
         testPackages.add(SECOND_TEST_PACKAGE);
         testPackages.add(THIRD_TEST_PACKAGE);
+        testPackages.add("android.server.cts.am");
         TEST_PACKAGES = Collections.unmodifiableList(testPackages);
     }
 
@@ -210,7 +217,7 @@
 
     /**
      * @return the am command to start the given activity with the following extra key/value pairs.
-     *         {@param keyValuePairs} must be a list of arguments defining each key/value extra.
+     * {@param keyValuePairs} must be a list of arguments defining each key/value extra.
      */
     // TODO: Make this more generic, for instance accepting flags or extras of other types.
     protected static String getAmStartCmd(final ComponentName activityName,
@@ -268,6 +275,10 @@
 
     protected ActivityAndWindowManagersState mAmWmState = new ActivityAndWindowManagersState();
 
+    public ActivityAndWindowManagersState getAmWmState() {
+        return mAmWmState;
+    }
+
     protected BroadcastActionTrigger mBroadcastActionTrigger = new BroadcastActionTrigger();
 
     /**
@@ -561,7 +572,7 @@
     }
 
     /**
-     * Launches {@param  activityName} into split-screen primary windowing mode and also makes
+     * Launches {@param activityName} into split-screen primary windowing mode and also makes
      * the recents activity visible to the side of it.
      * NOTE: Recents view may be combined with home screen on some devices, so using this to wait
      * for Recents only makes sense when {@link ActivityManagerState#isHomeRecentsComponent()} is
@@ -595,23 +606,24 @@
 
     /**
      * Moves the device into split-screen with the specified task into the primary stack.
-     * @param taskId        The id of the task to move into the primary stack.
-     * @param showRecents   Whether to show the recents activity (or a placeholder activity in
-     *                      place of the Recents activity if home is the recents component)
+     * @param taskId             The id of the task to move into the primary stack.
+     * @param showSideActivity   Whether to show the Recents activity (or a placeholder activity in
+     *                           place of the Recents activity if home is the recents component)
      */
-    public void moveTaskToPrimarySplitScreen(int taskId, boolean showRecents) {
+    public void moveTaskToPrimarySplitScreen(int taskId, boolean showSideActivity) {
+        final boolean isHomeRecentsComponent = mAmWmState.getAmState().isHomeRecentsComponent();
         SystemUtil.runWithShellPermissionIdentity(() -> {
             mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
                     SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true /* onTop */,
                     false /* animate */,
-                    null /* initialBounds */, showRecents);
+                    null /* initialBounds */, showSideActivity && !isHomeRecentsComponent);
             mAmWmState.waitForRecentsActivityVisible();
 
-            if (mAmWmState.getAmState().isHomeRecentsComponent() && showRecents) {
-                // Launch Placeholder Recents
-                final Activity recentsActivity = mSideActivityRule.launchActivity(
+            if (isHomeRecentsComponent && showSideActivity) {
+                // Launch Placeholder Side Activity
+                final Activity sideActivity = mSideActivityRule.launchActivity(
                         new Intent());
-                mAmWmState.waitForActivityState(recentsActivity.getComponentName(), STATE_RESUMED);
+                mAmWmState.waitForActivityState(sideActivity.getComponentName(), STATE_RESUMED);
             }
         });
     }
@@ -744,7 +756,7 @@
         assertTrue(message, mAmWmState.getAmState().hasActivityState(activityName, state));
     }
 
-    protected void waitAndAssertTopResumedActivity(ComponentName activityName, int displayId,
+    public void waitAndAssertTopResumedActivity(ComponentName activityName, int displayId,
             String message) {
         mAmWmState.waitForValidState(activityName);
         mAmWmState.waitForActivityState(activityName, STATE_RESUMED);
@@ -765,7 +777,7 @@
         mAmWmState.assertFocusedStack("Top activity's stack must also be on top", frontStackId);
         mAmWmState.assertVisibility(activityName, true /* visible */);
     }
-
+    
     // TODO: Switch to using a feature flag, when available.
     protected static boolean isUiModeLockedToVrHeadset() {
         final String output = runCommandAndPrintOutput("dumpsys uimode");
@@ -921,12 +933,22 @@
 
         private final boolean mIsLockDisabled;
         private boolean mLockCredentialSet;
+        private boolean mRemoveActivitiesOnClose;
+
+        public static final int FLAG_REMOVE_ACTIVITIES_ON_CLOSE = 1;
 
         public LockScreenSession() {
+            this(0 /* flags */);
+        }
+
+        public LockScreenSession(int flags) {
             mIsLockDisabled = isLockDisabled();
             mLockCredentialSet = false;
             // Enable lock screen (swipe) by default.
             setLockDisabled(false);
+            if ((flags & FLAG_REMOVE_ACTIVITIES_ON_CLOSE) != 0) {
+                mRemoveActivitiesOnClose = true;
+            }
         }
 
         public LockScreenSession setLockCredential() {
@@ -997,6 +1019,10 @@
 
         @Override
         public void close() {
+            if (mRemoveActivitiesOnClose) {
+                removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+            }
+
             setLockDisabled(mIsLockDisabled);
             if (mLockCredentialSet) {
                 removeLockCredential();
@@ -1042,6 +1068,10 @@
     /** Helper class to save, set & wait, and restore rotation related preferences. */
     protected class RotationSession extends SettingsSession<Integer> {
         private final SettingsSession<Integer> mUserRotation;
+        private final HandlerThread mThread;
+        private final Handler mRunnableHandler;
+        private final SettingsObserver mRotationObserver;
+        private int mPreviousDegree;
 
         public RotationSession() throws Exception {
             // Save accelerometer_rotation preference.
@@ -1050,23 +1080,82 @@
             mUserRotation = new SettingsSession<>(
                     Settings.System.getUriFor(Settings.System.USER_ROTATION),
                     Settings.System::getInt, Settings.System::putInt);
+
+            mThread = new HandlerThread("Observer_Thread");
+            mThread.start();
+            mRunnableHandler = new Handler(mThread.getLooper());
+            mRotationObserver = new SettingsObserver(mRunnableHandler);
+
+            mPreviousDegree = mUserRotation.get();
             // Disable accelerometer_rotation.
             super.set(0);
         }
 
         @Override
         public void set(@NonNull Integer value) throws Exception {
+            // When the rotation is locked and the SystemUI receives the rotation becoming 0deg, it
+            // will call freezeRotation to WMS, which will cause USER_ROTATION be set to zero again.
+            // In order to prevent our test target from being overwritten by SystemUI during
+            // rotation test, wait for the USER_ROTATION changed then continue testing.
+            final boolean waitSystemUI = value == ROTATION_0 && mPreviousDegree != ROTATION_0;
+            if (waitSystemUI) {
+                mRotationObserver.observe();
+            }
             mUserRotation.set(value);
+            mPreviousDegree = value;
+
+            if (waitSystemUI) {
+                waitForRotationNotified();
+            }
             // Wait for settling rotation.
             mAmWmState.waitForRotation(value);
+
+            if (waitSystemUI) {
+                mRotationObserver.stopObserver();
+            }
         }
 
         @Override
         public void close() throws Exception {
+            mThread.quitSafely();
             mUserRotation.close();
             // Restore accelerometer_rotation preference.
             super.close();
         }
+
+        private void waitForRotationNotified() {
+            for (int retry = 1; retry <= 5; retry++) {
+                if (mRotationObserver.notified) {
+                    return;
+                }
+                logAlways("waitForRotationNotified retry=" + retry);
+                SystemClock.sleep(500);
+            }
+            logE("waitForRotationNotified skip");
+        }
+
+        private class SettingsObserver extends ContentObserver {
+            boolean notified;
+
+            SettingsObserver(Handler handler) { super(handler); }
+
+            void observe() {
+                notified = false;
+                final ContentResolver resolver = mContext.getContentResolver();
+                resolver.registerContentObserver(Settings.System.getUriFor(
+                        Settings.System.USER_ROTATION), false, this);
+            }
+
+            void stopObserver() {
+                final ContentResolver resolver = mContext.getContentResolver();
+                resolver.unregisterContentObserver(this);
+            }
+
+            @Override
+            public void onChange(boolean selfChange) {
+                if (!selfChange) notified = true;
+            }
+        }
     }
 
     /**
@@ -1079,10 +1168,10 @@
      * rotation, because there is no requirement that an Android device that supports both
      * orientations needs to support user rotation mode.
      *
-     * @param session the rotation session used to set user rotation
+     * @param session   the rotation session used to set user rotation
      * @param displayId the display ID to check rotation against
      * @return {@code true} if test device respects settings of locked user rotation mode;
-     *      {@code false} if not.
+     * {@code false} if not.
      */
     protected boolean supportsLockedUserRotation(RotationSession session, int displayId)
             throws Exception {
@@ -1136,6 +1225,7 @@
     /**
      * Inserts a log separator so we can always find the starting point from where to evaluate
      * following logs.
+     *
      * @return Unique log separator.
      */
     protected LogSeparator separateLogs() {
@@ -1573,11 +1663,13 @@
         private enum LauncherType {
             INSTRUMENTATION, LAUNCHING_ACTIVITY, BROADCAST_RECEIVER
         }
+
         private LauncherType mLauncherType = LauncherType.LAUNCHING_ACTIVITY;
 
         public LaunchActivityBuilder(ActivityAndWindowManagersState amWmState) {
             mAmWmState = amWmState;
             mWaitForLaunched = true;
+            mWithShellPermission = true;
         }
 
         public LaunchActivityBuilder setToSide(boolean toSide) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
index 0eceaf4..459dffb 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
@@ -472,7 +472,7 @@
     /**
      * Check if there exists a window record with matching windowName.
      */
-    boolean containsWindow(String windowName) {
+    public boolean containsWindow(String windowName) {
         for (WindowState window : mWindowStates) {
             if (window.getName().equals(windowName)) {
                 return true;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index 1c82c6c..fb2f1b6 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -159,12 +159,12 @@
         sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, DEFAULT_DISPLAY);
 
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
-            final SecondaryActivity secondaryActivity
-                    = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+            final int secondaryDisplayId =
+                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final SecondaryActivity secondaryActivity =
+                    startActivity(SecondaryActivity.class, secondaryDisplayId);
             sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, INVALID_DISPLAY);
-            sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3,
-                    secondaryDisplay.getDisplayId());
+            sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3, secondaryDisplayId);
 
             final boolean perDisplayFocusEnabled = getTargetContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_perDisplayFocusEnabled);
@@ -177,7 +177,7 @@
 
             // Press display-unspecified keys and a display-specified key but not release them.
             sendKey(ACTION_DOWN, KEYCODE_5, INVALID_DISPLAY);
-            sendKey(ACTION_DOWN, KEYCODE_6, secondaryDisplay.getDisplayId());
+            sendKey(ACTION_DOWN, KEYCODE_6, secondaryDisplayId);
             sendKey(ACTION_DOWN, KEYCODE_7, INVALID_DISPLAY);
             secondaryActivity.assertAndConsumeKeyEvent(ACTION_DOWN, KEYCODE_5, 0 /* flags */);
             secondaryActivity.assertAndConsumeKeyEvent(ACTION_DOWN, KEYCODE_6, 0 /* flags */);
@@ -202,6 +202,33 @@
     }
 
     /**
+     * Test if a display targeted by a key event can be moved to top in a single-focus system.
+     */
+    @Test
+    public void testMovingDisplayToTopByKeyEvent() throws InterruptedException {
+        if (getTargetContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_perDisplayFocusEnabled)) {
+            return;
+        }
+
+        final PrimaryActivity primaryActivity = startActivity(PrimaryActivity.class,
+                DEFAULT_DISPLAY);
+
+        try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
+            final int secondaryDisplayId =
+                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final SecondaryActivity secondaryActivity =
+                    startActivity(SecondaryActivity.class, secondaryDisplayId);
+
+            sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_0, DEFAULT_DISPLAY);
+            sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, INVALID_DISPLAY);
+
+            sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, secondaryDisplayId);
+            sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3, INVALID_DISPLAY);
+        }
+    }
+
+    /**
      * Test if the client is notified about window-focus lost after the new focused window is drawn.
      */
     @Test
@@ -232,9 +259,10 @@
         primaryActivity.waitAndAssertPointerCaptureState(true /* hasCapture */);
 
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
-            final SecondaryActivity secondaryActivity
-                    = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+            final int secondaryDisplayId =
+                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final SecondaryActivity secondaryActivity =
+                    startActivity(SecondaryActivity.class, secondaryDisplayId);
 
             // Assert primary activity lost pointer capture when it is not top focused.
             primaryActivity.waitAndAssertPointerCaptureState(false /* hasCapture */);
@@ -260,9 +288,9 @@
 
         final SecondaryActivity secondaryActivity;
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
-            secondaryActivity
-                    = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+            final int secondaryDisplayId =
+                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            secondaryActivity = startActivity(SecondaryActivity.class, secondaryDisplayId);
         }
         // Secondary display disconnected.
 
diff --git a/tests/libcore/coreplatformapi/Android.mk b/tests/libcore/coreplatformapi/Android.mk
deleted file mode 100644
index 9dd2f17..0000000
--- a/tests/libcore/coreplatformapi/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsLibcoreCorePlatformApiTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    cts-core-test-runner \
-    core-platform-api-test
-
-# Don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_DEX_PREOPT := false
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/libcore/coreplatformapi/AndroidManifest.xml b/tests/libcore/coreplatformapi/AndroidManifest.xml
deleted file mode 100644
index 6b582a8..0000000
--- a/tests/libcore/coreplatformapi/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.libcore.cts.coreplatformapi"
-    android:targetSandboxVersion="2">
-
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:label="CTS Libcore core platform API test cases"
-        android:targetPackage="android.libcore.cts.coreplatformapi">
-    </instrumentation>
-</manifest>
diff --git a/tests/libcore/jsr166/AndroidTest.xml b/tests/libcore/jsr166/AndroidTest.xml
index 9d2cfcf..a05d91a 100644
--- a/tests/libcore/jsr166/AndroidTest.xml
+++ b/tests/libcore/jsr166/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore JSR166 test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/luni/AndroidTest.xml b/tests/libcore/luni/AndroidTest.xml
index 6de3df5..a069c4f 100644
--- a/tests/libcore/luni/AndroidTest.xml
+++ b/tests/libcore/luni/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/ojluni/AndroidTest.xml b/tests/libcore/ojluni/AndroidTest.xml
index 589d431..d49736b 100644
--- a/tests/libcore/ojluni/AndroidTest.xml
+++ b/tests/libcore/ojluni/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore OJ test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/okhttp/AndroidTest.xml b/tests/libcore/okhttp/AndroidTest.xml
index 1865fa5..c6ca3d9 100644
--- a/tests/libcore/okhttp/AndroidTest.xml
+++ b/tests/libcore/okhttp/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore OkHttp test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
         <option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/simplemmodule/AndroidManifest.xml b/tests/libcore/simplemmodule/AndroidManifest.xml
deleted file mode 100644
index ed825b3..0000000
--- a/tests/libcore/simplemmodule/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.libcore.cts.simplemmodule"
-    android:targetSandboxVersion="2">
-
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:label="CTS Libcore simple mmodule test cases"
-        android:targetPackage="android.libcore.cts.simplemmodule">
-    </instrumentation>
-</manifest>
diff --git a/tests/libcore/simplemmodule/AndroidTest.xml b/tests/libcore/simplemmodule/AndroidTest.xml
deleted file mode 100644
index 5eb0586..0000000
--- a/tests/libcore/simplemmodule/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS Libcore simple mmodule test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="libcore" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsLibcoreSimpleMModuleTestCases.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.libcore.cts.simplemmodule" />
-        <option name="runtime-hint" value="1m"/>
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
diff --git a/tests/libcore/wycheproof-bc/AndroidTest.xml b/tests/libcore/wycheproof-bc/AndroidTest.xml
index badcaec..f137d92 100644
--- a/tests/libcore/wycheproof-bc/AndroidTest.xml
+++ b/tests/libcore/wycheproof-bc/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore Wycheproof Bouncy Castle test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <!-- this has just the instrumentation which acts as the tests we want to run -->
diff --git a/tests/libcore/wycheproof/AndroidTest.xml b/tests/libcore/wycheproof/AndroidTest.xml
index 0119e6b..4870a52 100644
--- a/tests/libcore/wycheproof/AndroidTest.xml
+++ b/tests/libcore/wycheproof/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Libcore Wycheproof Conscrypt test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <!-- this has just the instrumentation which acts as the tests we want to run -->
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 959e04d..4dcb1e8 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -26,6 +26,7 @@
 
 import android.app.Activity;
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.Intent;
 import android.content.UriPermission;
@@ -326,7 +327,9 @@
     }
 
     private void onScanCompleted(Uri uri, CountDownLatch latch) {
-        mMediaStoreUri = uri;
+        final String volumeName = MediaStore.getVolumeName(uri);
+        mMediaStoreUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri(volumeName),
+                ContentUris.parseId(uri));
         latch.countDown();
     }
 
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 08afe97..bb2c28c 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -32,6 +32,7 @@
     cts-signature-common \
     repackaged.android.test.base \
     repackaged.android.test.runner \
+    compatibility-device-util
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml b/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
index 877e911..7ad6c9e 100644
--- a/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
@@ -22,7 +22,7 @@
 
     <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="27"/>
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.android_test_base_27"
diff --git a/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
index f0fc8e1..15af902 100644
--- a/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application android:debuggable="true">
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.mock"/>
     </application>
 
diff --git a/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
index f81665e..e055a9f 100644
--- a/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application android:debuggable="true">
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner"/>
     </application>
 
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
index ae69f52..f118565 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
@@ -22,7 +22,7 @@
 
     <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="27"/>
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.apache_http_legacy_27"
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
index f0fb7d8..1497557 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.apache_http_legacy_current"
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
index f759c54..7749a8b 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application>
+    <application android:extractNativeLibs="true">
         <uses-library android:name="org.apache.http.legacy"/>
     </application>
 
diff --git a/tests/signature/api-check/current-api/AndroidManifest.xml b/tests/signature/api-check/current-api/AndroidManifest.xml
index d6f474b..163d5f2 100644
--- a/tests/signature/api-check/current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.current"
diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
index 838112f..eca5c45 100644
--- a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
@@ -21,7 +21,7 @@
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <uses-sdk android:targetSdkVersion="27" />
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation
         android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
index 51b986e..6325522 100644
--- a/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
@@ -21,7 +21,7 @@
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <uses-sdk android:targetSdkVersion="28" />
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation
         android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
index 12d0393..4d28816 100644
--- a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation
         android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
index 8586df6..7dd2824 100644
--- a/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation
         android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
index 1bd686b..a752b2f 100644
--- a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.signature.cts.api.killswitch_debug_class">
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.killswitch_debug_class"
diff --git a/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
index 5b023af..12b35da 100644
--- a/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.signature.cts.api.killswitch_whitelist">
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.killswitch_whitelist"
diff --git a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
index 68f3acf..1a73cd0 100644
--- a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.signature.cts.api.killswitch_wildcard">
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.killswitch_wildcard"
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
new file mode 100644
index 0000000..4de233f
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_JAVA_SDK_LIBRARIES := \
+        android.test.base \
+        android.test.mock \
+        android.test.runner \
+        com.android.future.usb.accessory \
+        com.android.location.provider \
+        com.android.mediadrm.signer \
+        com.android.media.remotedisplay \
+        com.android.media.tv.remoteprovider \
+        com.android.nfc_extras \
+        javax.obex \
+        org.apache.http.legacy
+
+$(foreach ver,28,\
+  $(foreach api_level,public system,\
+    $(foreach lib,$(LOCAL_JAVA_SDK_LIBRARIES),\
+      $(eval all_shared_libs_files += $(lib)-$(ver)-$(api_level).api))))
+
+
+LOCAL_PACKAGE_NAME := CtsSharedLibsApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    $(all_shared_libs_files)
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
+
+LOCAL_JAVA_SDK_LIBRARIES :=
+all_shared_libs_files :=
+
diff --git a/tests/signature/api-check/shared-libs-api/AndroidManifest.xml b/tests/signature/api-check/shared-libs-api/AndroidManifest.xml
new file mode 100644
index 0000000..c2bc448
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.signature.cts.api.shared_libs">
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+
+    <application android:extractNativeLibs="true">
+        <uses-library android:name="android.test.base" android:required="false"/>
+        <uses-library android:name="android.test.mock" android:required="false"/>
+        <uses-library android:name="android.test.runner" android:required="false"/>
+        <uses-library android:name="com.android.future.usb.accessory" android:required="false"/>
+        <uses-library android:name="com.android.location.provider" android:required="false"/>
+        <uses-library android:name="com.android.mediadrm.signer" android:required="false"/>
+        <uses-library android:name="com.android.media.remotedisplay" android:required="false"/>
+        <uses-library android:name="com.android.media.tv.remoteprovider" android:required="false"/>
+        <uses-library android:name="com.android.nfc_extras" android:required="false"/>
+        <uses-library android:name="javax.obex" android:required="false"/>
+        <uses-library android:name="org.apache.http.legacy" android:required="false"/>
+    </application>
+
+    <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
+                     android:targetPackage="android.signature.cts.api.shared_libs"
+                     android:label="Shared Libraries API Signature Muti Libs Test"/>
+
+</manifest>
diff --git a/tests/signature/api-check/shared-libs-api/AndroidTest.xml b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
new file mode 100644
index 0000000..2e42061
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for CTS Shared Libraries API Signature test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="systems" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/signature-test" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android.test.base-28-public.api->/data/local/tmp/signature-test/android.test.base-28-public.api" />
+        <option name="push" value="android.test.mock-28-public.api->/data/local/tmp/signature-test/android.test.mock-28-public.api" />
+        <option name="push" value="android.test.runner-28-public.api->/data/local/tmp/signature-test/android.test.runner-28-public.api" />
+        <option name="push" value="com.android.future.usb.accessory-28-public.api->/data/local/tmp/signature-test/com.android.future.usb.accessory-28-public.api" />
+        <option name="push" value="com.android.location.provider-28-public.api->/data/local/tmp/signature-test/com.android.location.provider-28-public.api" />
+        <option name="push" value="com.android.mediadrm.signer-28-public.api->/data/local/tmp/signature-test/com.android.mediadrm.signer-28-public.api" />
+        <option name="push" value="com.android.media.remotedisplay-28-public.api->/data/local/tmp/signature-test/com.android.media.remotedisplay-28-public.api" />
+        <option name="push" value="com.android.media.tv.remoteprovider-28-public.api->/data/local/tmp/signature-test/com.android.media.tv.remoteprovider-28-public.api" />
+        <option name="push" value="com.android.nfc_extras-28-public.api->/data/local/tmp/signature-test/com.android.nfc_extras-28-public.api" />
+        <option name="push" value="javax.obex-28-public.api->/data/local/tmp/signature-test/javax.obex-28-public.api" />
+        <option name="push" value="org.apache.http.legacy-28-public.api->/data/local/tmp/signature-test/org.apache.http.legacy-28-public.api" />
+        <option name="push" value="android.test.base-28-system.api->/data/local/tmp/signature-test/android.test.base-28-system.api" />
+        <option name="push" value="android.test.mock-28-system.api->/data/local/tmp/signature-test/android.test.mock-28-system.api" />
+        <option name="push" value="android.test.runner-28-system.api->/data/local/tmp/signature-test/android.test.runner-28-system.api" />
+        <option name="push" value="com.android.future.usb.accessory-28-system.api->/data/local/tmp/signature-test/com.android.future.usb.accessory-28-system.api" />
+        <option name="push" value="com.android.location.provider-28-system.api->/data/local/tmp/signature-test/com.android.location.provider-28-system.api" />
+        <option name="push" value="com.android.mediadrm.signer-28-system.api->/data/local/tmp/signature-test/com.android.mediadrm.signer-28-system.api" />
+        <option name="push" value="com.android.media.remotedisplay-28-system.api->/data/local/tmp/signature-test/com.android.media.remotedisplay-28-system.api" />
+        <option name="push" value="com.android.media.tv.remoteprovider-28-system.api->/data/local/tmp/signature-test/com.android.media.tv.remoteprovider-28-system.api" />
+        <option name="push" value="com.android.nfc_extras-28-system.api->/data/local/tmp/signature-test/com.android.nfc_extras-28-system.api" />
+        <option name="push" value="javax.obex-28-system.api->/data/local/tmp/signature-test/javax.obex-28-system.api" />
+        <option name="push" value="org.apache.http.legacy-28-system.api->/data/local/tmp/signature-test/org.apache.http.legacy-28-system.api" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSharedLibsApiSignatureTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.signature.cts.api.shared_libs" />
+        <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
+        <option name="class" value="android.signature.cts.api.SignatureMultiLibsTest" />
+        <option name="instrumentation-arg" key="library-names" value="android.test.base,android.test.mock,android.test.runner,com.android.future.usb.accessory,com.android.location.provider,com.android.mediadrm.signer,com.android.media.remotedisplay,com.android.media.tv.remoteprovider,com.android.nfc_extras,javax.obex,org.apache.http.legacy" />
+        <option name="instrumentation-arg" key="versions" value="28" />
+        <option name="instrumentation-arg" key="api_levels" value="public,system" />
+        <option name="runtime-hint" value="30s" />
+    </test>
+</configuration>
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java
new file mode 100644
index 0000000..772155a
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 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.signature.cts.api;
+
+import android.os.Bundle;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.stream.Stream;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
+/**
+ * Performs the signature check via a JUnit test.
+ */
+public class SignatureMultiLibsTest extends SignatureTest {
+
+    private static final String TAG = SignatureMultiLibsTest.class.getSimpleName();
+
+    private String[] libraryNames;
+    private String[] versions;
+    private String[] api_levels;
+
+    @Override
+    protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
+        libraryNames = getCommaSeparatedList(instrumentationArgs, "library-names");
+        versions = getCommaSeparatedList(instrumentationArgs, "versions");
+        api_levels = getCommaSeparatedList(instrumentationArgs, "api_levels");
+        super.initializeFromArgs(instrumentationArgs);
+    }
+
+    /**
+     * Tests that the device's API matches the expected set defined in xml.
+     * <p/>
+     * Will check the entire API, and then report the complete list of failures
+     */
+    @Override
+    public void testSignature() {
+        Stream<String> packageListLibraries = getLibraries();
+        ArrayList<String> expected = new ArrayList<>();
+        packageListLibraries.forEach(lib -> {
+            if (Arrays.asList(libraryNames).indexOf(lib) >= 0) {
+                for (String ver : versions) {
+                    for (String api_level : api_levels) {
+                        expected.add(lib + "-" + ver + "-" + api_level + ".api");
+                    }
+                }
+            }
+        });
+        expectedApiFiles = expected.toArray(new String[expected.size()]);
+
+        super.testSignature();
+    }
+
+    private Stream<String> getLibraries() {
+        try {
+            String result = runShellCommand(getInstrumentation(), "cmd package list libraries");
+            return Arrays.stream(result.split("\n")).map(line -> line.split(":")[1]);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
index fadf748..7861df7 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
@@ -38,8 +38,8 @@
 
     private static final String TAG = SignatureTest.class.getSimpleName();
 
-    private String[] expectedApiFiles;
-    private String[] baseApiFiles;
+    protected String[] expectedApiFiles;
+    protected String[] baseApiFiles;
     private String[] unexpectedApiFiles;
 
     @Override
diff --git a/tests/signature/api-check/system-annotation/AndroidManifest.xml b/tests/signature/api-check/system-annotation/AndroidManifest.xml
index 74a9b49..fb72cb3 100644
--- a/tests/signature/api-check/system-annotation/AndroidManifest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidManifest.xml
@@ -22,7 +22,7 @@
 
     <uses-sdk android:targetSdkVersion="28" />
 
-    <application android:debuggable="true"/>
+    <application android:debuggable="true" android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.system_annotation"
diff --git a/tests/signature/api-check/system-api/AndroidManifest.xml b/tests/signature/api-check/system-api/AndroidManifest.xml
index 1f7bed8..9df3ddd 100644
--- a/tests/signature/api-check/system-api/AndroidManifest.xml
+++ b/tests/signature/api-check/system-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application/>
+    <application android:extractNativeLibs="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
                      android:targetPackage="android.signature.cts.api.system"
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
index 5a95155..2162eec 100644
--- a/tests/signature/api/Android.mk
+++ b/tests/signature/api/Android.mk
@@ -50,6 +50,27 @@
   )\
 )
 
+LOCAL_JAVA_SDK_LIBRARIES := \
+        android.test.base \
+        android.test.mock \
+        android.test.runner \
+        com.android.future.usb.accessory \
+        com.android.location.provider \
+        com.android.mediadrm.signer \
+        com.android.media.remotedisplay \
+        com.android.media.tv.remoteprovider \
+        com.android.nfc_extras \
+        javax.obex \
+        org.apache.http.legacy
+
+$(foreach ver,28,\
+  $(foreach api_level,public system,\
+    $(foreach lib,$(LOCAL_JAVA_SDK_LIBRARIES),\
+      $(eval $(call build_xml_api_file,$(lib)-$(ver)-$(api_level).api,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)))))
+
+LOCAL_JAVA_SDK_LIBRARIES :=
+
+
 # current apache-http-legacy minus current api, in text format.
 # =============================================================
 # Removes any classes from the org.apache.http.legacy API description that are
diff --git a/tests/signature/runSignatureTests.sh b/tests/signature/runSignatureTests.sh
index fead7c7..046300f 100755
--- a/tests/signature/runSignatureTests.sh
+++ b/tests/signature/runSignatureTests.sh
@@ -33,6 +33,8 @@
 CtsHiddenApiKillswitchWildcardTestCases
 CtsHiddenApiKillswitchWhitelistTestCases
 CtsHiddenApiKillswitchDebugClassTestCases
+
+CtsSharedLibsApiSignatureTestCases
 "
 else
     PACKAGES=${1+"$@"}
diff --git a/tests/tests/app.usage/Android.mk b/tests/tests/app.usage/Android.mk
index 9beeeaa..2f1513be 100644
--- a/tests/tests/app.usage/Android.mk
+++ b/tests/tests/app.usage/Android.mk
@@ -41,3 +41,4 @@
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml
index b8d60bf..3d650fc 100644
--- a/tests/tests/app.usage/AndroidManifest.xml
+++ b/tests/tests/app.usage/AndroidManifest.xml
@@ -50,6 +50,7 @@
         <activity android:name=".ActivityTransitionActivity2"
             android:taskAffinity="android.app.usage.cts.other_task"/>
         <activity android:name=".FragmentTestActivity" />
+        <activity android:name=".TaskRootActivity" />
         <service android:name=".TestService" />
     </application>
 
diff --git a/tests/tests/app.usage/AndroidTest.xml b/tests/tests/app.usage/AndroidTest.xml
index 8fba812..f611fbe 100644
--- a/tests/tests/app.usage/AndroidTest.xml
+++ b/tests/tests/app.usage/AndroidTest.xml
@@ -22,6 +22,7 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsUsageStatsTestCases.apk" />
+        <option name="test-file-name" value="CtsUsageStatsTestApp1.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.app.usage.cts" />
diff --git a/tests/tests/text/Android.mk b/tests/tests/app.usage/TestApp1/Android.mk
similarity index 76%
rename from tests/tests/text/Android.mk
rename to tests/tests/app.usage/TestApp1/Android.mk
index ffa5f9eb..76d2f47 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/app.usage/TestApp1/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,29 +16,28 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsUsageStatsTestApp1
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
 # don't include this package in any target
 LOCAL_MODULE_TAGS := optional
+
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
-    compatibility-device-util \
-    ctsdeviceutillegacy \
-    ctstestrunner \
+LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
-    mockito-target-minus-junit4 \
+    compatibility-device-util \
+    ctstestrunner \
+    cts-amwm-util \
+    junit \
     ub-uiautomator
 
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs android.test.runner.stubs
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsTextTestCases
-
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
-
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app.usage/TestApp1/AndroidManifest.xml b/tests/tests/app.usage/TestApp1/AndroidManifest.xml
new file mode 100644
index 0000000..d4306e5
--- /dev/null
+++ b/tests/tests/app.usage/TestApp1/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.app.usage.cts.test1">
+
+    <application>
+        <activity android:name=".SomeActivity"
+                  android:exported="true"
+        />
+    </application>
+</manifest>
diff --git a/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java b/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java
new file mode 100644
index 0000000..9d2ca8e
--- /dev/null
+++ b/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2019 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.app.usage.cts.test1;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public final class SomeActivity extends Activity {
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java b/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java
new file mode 100644
index 0000000..e0f7fc6
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2019 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.app.usage.cts;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.view.WindowManager;
+
+public class TaskRootActivity extends Activity  {
+    public static final String TEST_APP_PKG = "android.app.usage.cts.test1";
+    public static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
+    private static final long TIMEOUT = 5000;
+    private UiDevice mUiDevice;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Intent intent = new Intent();
+        intent.setClassName(TEST_APP_PKG, TEST_APP_CLASS);
+        startActivity(intent);
+        mUiDevice.wait(Until.hasObject(By.clazz(TEST_APP_PKG, TEST_APP_CLASS)), TIMEOUT);
+    }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 44dfc5a..99fbff7 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -54,11 +54,13 @@
 
 import com.android.compatibility.common.util.AppStandbyUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -88,6 +90,15 @@
     private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} " +
             AppOpsManager.OPSTR_GET_USAGE_STATS + " {1}";
 
+    private static final String USAGE_SOURCE_GET_SHELL_COMMAND = "settings get global " +
+            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+
+    private static final String USAGE_SOURCE_SET_SHELL_COMMAND = "settings put global " +
+            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE + " {0}";
+
+    private static final String USAGE_SOURCE_DELETE_SHELL_COMMAND = "settings delete global " +
+            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+
     private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
     private static final long MINUTE = TimeUnit.MINUTES.toMillis(1);
     private static final long DAY = TimeUnit.DAYS.toMillis(1);
@@ -101,6 +112,7 @@
     private UiDevice mUiDevice;
     private UsageStatsManager mUsageStatsManager;
     private String mTargetPackage;
+    private String mCachedUsageSourceSetting;
 
     @Before
     public void setUp() throws Exception {
@@ -110,6 +122,16 @@
         mTargetPackage = InstrumentationRegistry.getContext().getPackageName();
         assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
         setAppOpsMode("allow");
+        mCachedUsageSourceSetting = getUsageSourceSetting();
+    }
+
+
+    @After
+    public void cleanUp() throws Exception {
+        if (!mCachedUsageSourceSetting.equals(getUsageSourceSetting())) {
+            setUsageSourceSetting(mCachedUsageSourceSetting);
+            mUsageStatsManager.forceUsageSourceSettingRead();
+        }
     }
 
     private static void assertLessThan(long left, long right) {
@@ -126,6 +148,22 @@
         mUiDevice.executeShellCommand(command);
     }
 
+
+    private String getUsageSourceSetting() throws Exception {
+        return mUiDevice.executeShellCommand(USAGE_SOURCE_GET_SHELL_COMMAND);
+    }
+
+    private void setUsageSourceSetting(String usageSource) throws Exception {
+        if (usageSource.equals("null")) {
+            mUiDevice.executeShellCommand(USAGE_SOURCE_DELETE_SHELL_COMMAND);
+        } else {
+            final String command = MessageFormat.format(USAGE_SOURCE_SET_SHELL_COMMAND,
+                                                        usageSource);
+            mUiDevice.executeShellCommand(command);
+        }
+        mUsageStatsManager.forceUsageSourceSettingRead();
+    }
+
     private void launchSubActivity(Class<? extends Activity> clazz) {
         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
         final Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -869,20 +907,57 @@
     }
 
     @Test
-    public void testObserveUsagePermission() {
+    public void testObserveUsagePermissionForRegisterObserver() {
+        final int observerId = 0;
+        final String[] packages = new String[] {"com.android.settings"};
+
         try {
-            mUsageStatsManager.registerAppUsageObserver(0, new String[] {"com.android.settings"},
+            mUsageStatsManager.registerAppUsageObserver(observerId, packages,
                     1, java.util.concurrent.TimeUnit.HOURS, null);
-            fail("Should throw SecurityException");
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
         } catch (SecurityException e) {
             // Exception expected
         }
 
         try {
-            mUsageStatsManager.registerUsageSessionObserver(0, new String[]{"com.android.settings"},
+            mUsageStatsManager.registerUsageSessionObserver(observerId, packages,
                     1, java.util.concurrent.TimeUnit.HOURS, 10,
                     java.util.concurrent.TimeUnit.SECONDS, null, null);
-            fail("Should throw SecurityException");
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+        } catch (SecurityException e) {
+            // Exception expected
+        }
+
+        try {
+            mUsageStatsManager.registerAppUsageLimitObserver(observerId, packages,
+                    1, java.util.concurrent.TimeUnit.HOURS, null);
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+        } catch (SecurityException e) {
+            // Exception expected
+        }
+    }
+
+    @Test
+    public void testObserveUsagePermissionForUnregisterObserver() {
+        final int observerId = 0;
+
+        try {
+            mUsageStatsManager.unregisterAppUsageObserver(observerId);
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+        } catch (SecurityException e) {
+            // Exception expected
+        }
+
+        try {
+            mUsageStatsManager.unregisterUsageSessionObserver(observerId);
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+        } catch (SecurityException e) {
+            // Exception expected
+        }
+
+        try {
+            mUsageStatsManager.unregisterAppUsageLimitObserver(observerId);
+            fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
         } catch (SecurityException e) {
             // Exception expected
         }
@@ -927,6 +1002,68 @@
         assertLessThan(startIdx, stopIdx);
     }
 
+    @AppModeFull // No usage events access in instant apps
+    @Test
+    public void testTaskRootEventField() throws Exception {
+        final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
+                .getContext().getSystemService(KeyguardManager.class);
+        mUiDevice.wakeUp();
+        // Also want to start out with the keyguard dismissed.
+        if (kmgr.isKeyguardLocked()) {
+            final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
+            mUiDevice.executeShellCommand("wm dismiss-keyguard");
+            ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
+            assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
+            SystemClock.sleep(500);
+        }
+
+        final long startTime = System.currentTimeMillis();
+        launchSubActivity(TaskRootActivity.class);
+        final long endTime = System.currentTimeMillis();
+        UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
+
+        while (events.hasNextEvent()) {
+            UsageEvents.Event event = new UsageEvents.Event();
+            assertTrue(events.getNextEvent(event));
+            if (TaskRootActivity.TEST_APP_PKG.equals(event.getPackageName())
+                    && TaskRootActivity.TEST_APP_CLASS.equals(event.getClassName())) {
+                assertEquals(mTargetPackage, event.getTaskRootPackageName());
+                assertEquals(TaskRootActivity.class.getCanonicalName(),
+                        event.getTaskRootClassName());
+                return;
+            }
+        }
+        fail("Did not find nested activity name in usage events");
+    }
+
+    @Test
+    public void testUsageSourceAttribution() throws Exception {
+        final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
+                .getContext().getSystemService(KeyguardManager.class);
+        mUiDevice.wakeUp();
+        // Also want to start out with the keyguard dismissed.
+        if (kmgr.isKeyguardLocked()) {
+            final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
+            mUiDevice.executeShellCommand("wm dismiss-keyguard");
+            ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
+            assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
+            SystemClock.sleep(500);
+        }
+
+        setUsageSourceSetting(Integer.toString(mUsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY));
+        launchSubActivity(TaskRootActivity.class);
+        // Usage should be attributed to the test app package
+        assertAppOrTokenUsed(TaskRootActivity.TEST_APP_PKG, true);
+
+        mUiDevice.pressHome();
+
+        setUsageSourceSetting(Integer.toString(
+                mUsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY));
+        launchSubActivity(TaskRootActivity.class);
+        // Usage should be attributed to this package
+        assertAppOrTokenUsed(mTargetPackage, true);
+    }
+
     private void pressWakeUp() {
         mUiDevice.pressKeyCode(KeyEvent.KEYCODE_WAKEUP);
     }
@@ -934,4 +1071,30 @@
     private void pressSleep() {
         mUiDevice.pressKeyCode(KeyEvent.KEYCODE_SLEEP);
     }
+
+    /**
+     * Assert on an app or token's usage state.
+     * @param entity name of the app or token
+     * @param expected expected usage state, true for in use, false for not in use
+     */
+    private void assertAppOrTokenUsed(String entity, boolean expected) throws IOException {
+        final String activeUsages =
+                mUiDevice.executeShellCommand("dumpsys usagestats apptimelimit actives");
+        final String[] actives = activeUsages.split("\n");
+        boolean found = false;
+
+        for (String active : actives) {
+            if (active.equals(entity)) {
+                found = true;
+                break;
+            }
+        }
+        if (expected) {
+            assertTrue(entity + " not found in list of active activities and tokens\n"
+                    + activeUsages, found);
+        } else {
+            assertFalse(entity + " found in list of active activities and tokens\n"
+                    + activeUsages, found);
+        }
+    }
 }
diff --git a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
index 9ab06d5..1a749b0 100644
--- a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
@@ -224,7 +224,7 @@
                 if (d > 0) {
                     val previousIntervalDuration = computeIntervalDurationMillis(d - 1)
                     val currentIntervalDuration = computeIntervalDurationMillis(d)
-                    val sleepDurationMillis = (previousIntervalDuration / 2
+                    val sleepDurationMillis = (previousIntervalDuration
                             + currentIntervalDuration / 2)
                     SystemClock.sleep(sleepDurationMillis)
                 }
@@ -318,7 +318,8 @@
         try {
             lock.lock()
             appOpsManager.getHistoricalOps(uid, packageName, opNames,
-                    beginTimeMillis, endTimeMillis, null, { ops ->
+                    beginTimeMillis, endTimeMillis, getContext().getMainExecutor(),
+                    Consumer { ops ->
                 array[0] = ops
                 try {
                     lock.lock()
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index a41b507..937d8ce 100755
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -16,8 +16,11 @@
 package android.assist.common;
 
 import android.content.ComponentName;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.LocaleList;
+import android.os.Process;
+import android.util.Log;
 
 import org.json.JSONObject;
 
@@ -25,6 +28,7 @@
 import java.util.Locale;
 
 public class Utils {
+    private static final String TAG = Utils.class.getSimpleName();
     public static final String TESTCASE_TYPE = "testcase_type";
     public static final String TESTINFO = "testinfo";
     public static final String ACTION_PREFIX = "android.intent.action.";
@@ -116,6 +120,8 @@
     private static Bundle EXTRA_ASSIST_BUNDLE;
     private static String STRUCTURED_JSON;
 
+    private static String MY_UID_EXTRA = "my_uid";
+
     public static final String getStructuredJSON() throws Exception {
         if (STRUCTURED_JSON == null) {
             STRUCTURED_JSON = new JSONObject()
@@ -139,15 +145,24 @@
     public static final Bundle getExtraAssistBundle() {
         if (EXTRA_ASSIST_BUNDLE == null) {
             EXTRA_ASSIST_BUNDLE = new Bundle();
-            addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE);
+            addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE, /* addMyUid= */ false);
         }
         return EXTRA_ASSIST_BUNDLE;
     }
 
     public static void addExtraAssistDataToBundle(Bundle data) {
+        addExtraAssistDataToBundle(data, /* addMyUid= */ true);
+
+    }
+
+    private static void addExtraAssistDataToBundle(Bundle data, boolean addMyUid) {
         data.putString("hello", "there");
         data.putBoolean("isthis_true_or_false", true);
         data.putInt("number", 123);
+        if (addMyUid) {
+            Log.i(TAG, "adding " + MY_UID_EXTRA + "=" + Process.myUid());
+            data.putInt(MY_UID_EXTRA, Process.myUid());
+        }
     }
 
     /** The shim activity that starts the service associated with each test. */
@@ -248,4 +263,8 @@
         testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE))
             .add(TEST_ERROR + " " + msg);
     }
+
+    public static int getExpectedUid(Bundle extras) {
+        return extras.getInt(MY_UID_EXTRA);
+    }
 }
diff --git a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
index 1154179..5717fcc 100644
--- a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
+import android.os.Process;
 import android.util.Log;
 
 import java.util.concurrent.CountDownLatch;
@@ -80,10 +81,9 @@
 
         Log.i(TAG, "assist bundle is: " + Utils.toBundleString(mAssistBundle));
 
-        // tests that the assist content's structured data is the expected
+        // first tests that the assist content's structured data is the expected
         assertEquals("AssistContent structured data did not match data in onProvideAssistContent",
                 Utils.getStructuredJSON(), mAssistContent.getStructuredData());
-        // tests the assist data. EXTRA_ASSIST_CONTEXT is what's expected.
         Bundle extraExpectedBundle = Utils.getExtraAssistBundle();
         Bundle extraAssistBundle = mAssistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
         for (String key : extraExpectedBundle.keySet()) {
@@ -92,6 +92,12 @@
             assertEquals("Extra assist context bundle values do not match for key: " + key,
                     extraExpectedBundle.get(key), extraAssistBundle.get(key));
         }
+
+        // then test the EXTRA_ASSIST_UID
+        int expectedUid = Utils.getExpectedUid(extraAssistBundle);
+        int actualUid = mAssistBundle.getInt(Intent.EXTRA_ASSIST_UID);
+        assertEquals("Wrong value for EXTRA_ASSIST_UID", expectedUid, actualUid);
+
     }
 
     private void waitForOnResume() throws Exception {
diff --git a/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java b/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
index 0cb8801..4b4c909 100644
--- a/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
+++ b/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
@@ -29,10 +29,6 @@
  */
 public class ExtraAssistDataActivity extends Activity {
     private static final String TAG = "ExtraAssistDataActivity";
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
 
     @Override
     public void onProvideAssistData(Bundle data) {
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
index 5a24284..9a4e3dd 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
@@ -35,6 +35,15 @@
 using ::ndk::SharedRefBase;
 using ::ndk::SpAIBinder;
 
+// AIDL tests which are independent of the service
+class NdkBinderTest_AidlLocal : public NdkBinderTest {};
+
+TEST_F(NdkBinderTest_AidlLocal, FromBinder) {
+  std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
+  SpAIBinder binder = test->asBinder();
+  EXPECT_EQ(test, ITest::fromBinder(binder));
+}
+
 struct Params {
   std::shared_ptr<ITest> iface;
   bool shouldBeRemote;
@@ -45,6 +54,8 @@
 #define iface GetParam().iface
 #define shouldBeRemote GetParam().shouldBeRemote
 
+// AIDL tests which run on each type of service (local C++, local Java, remote C++, remote Java,
+// etc..)
 class NdkBinderTest_Aidl : public NdkBinderTest,
                            public ::testing::WithParamInterface<Params> {};
 
@@ -553,6 +564,9 @@
 
 std::shared_ptr<ITest> getLocalService() {
   // BpTest -> AIBinder -> test
+  //
+  // Warning: for testing purposes only. This parcels things within the same process for testing
+  // purposes. In normal usage, this should just return SharedRefBase::make<MyTest> directly.
   std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
   return BpTest::associate(test->asBinder());
 }
diff --git a/tests/tests/bionic/Android.build.copy.libs.mk b/tests/tests/bionic/Android.build.copy.libs.mk
index a1bd707..f346b8a 100644
--- a/tests/tests/bionic/Android.build.copy.libs.mk
+++ b/tests/tests/bionic/Android.build.copy.libs.mk
@@ -16,6 +16,7 @@
   dt_runpath_b_c_x/libtest_dt_runpath_b.so \
   dt_runpath_b_c_x/libtest_dt_runpath_c.so \
   dt_runpath_b_c_x/libtest_dt_runpath_x.so \
+  elftls_dlopen_ie_error_helper/elftls_dlopen_ie_error_helper \
   exec_linker_helper/exec_linker_helper \
   exec_linker_helper_lib.so \
   inaccessible_libs/libtestshared.so \
@@ -74,6 +75,9 @@
   libtest_dlsym_from_this_grandchild.so \
   libtest_dlsym_weak_func.so \
   libtest_dt_runpath_d.so \
+  libtest_elftls_shared_var.so \
+  libtest_elftls_shared_var_ie.so \
+  libtest_elftls_tprel.so \
   libtest_empty.so \
   libtest_indirect_thread_local_dtor.so \
   libtest_init_fini_order_child.so \
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index 301a384..ec21b5c 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -17,15 +17,18 @@
     libdl_preempt_test_1 \
     libdl_preempt_test_2 \
     libdl_test_df_1_global \
+    libtest_elftls_shared_var \
+    libtest_elftls_tprel \
 
 LOCAL_WHOLE_STATIC_LIBRARIES += \
     libBionicTests \
     libBionicLoaderTests \
+    libBionicElfTlsLoaderTests \
     libBionicCtsGtestMain \
 
 LOCAL_STATIC_LIBRARIES += \
     libbase \
-    libpagemap \
+    libmeminfo \
     libziparchive \
     libtinyxml2 \
     liblog \
diff --git a/tests/tests/bionic/AndroidTest.xml b/tests/tests/bionic/AndroidTest.xml
index f6d2b09..af3c65b 100644
--- a/tests/tests/bionic/AndroidTest.xml
+++ b/tests/tests/bionic/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Config for CTS Bionic test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="bionic" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
         <option name="push" value="CtsBionicTestCases->/data/local/tmp/CtsBionicTestCases" />
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index 4eb9cd9..0cf4065 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -20,6 +20,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
index cb59a0a3..905c821 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -91,7 +91,7 @@
             TestUtils.enableLocation(getContext());
         }
         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
-                "android.bluetooth.cts", android.Manifest.permission.ACCESS_COARSE_LOCATION);
+                "android.bluetooth.cts", android.Manifest.permission.ACCESS_FINE_LOCATION);
     }
 
     @Override
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java
new file mode 100644
index 0000000..7336f3b
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.cts;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Unit test cases for {@link BluetoothHearingAid}.
+ * <p>
+ * To run the test, use adb shell am instrument -e class 'android.bluetooth.HearingAidProfileTest' 
+ * -w 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner' 
+ */
+public class HearingAidProfileTest extends AndroidTestCase {
+    private static final String TAG = "HearingAidProfileTest";
+
+    private static final int WAIT_FOR_INTENT_TIMEOUT_MS = 10000; // ms to wait for intent callback
+    private static final int PROXY_CONNECTION_TIMEOUT_MS = 500;  // ms timeout for Proxy Connect
+    private static final int ADAPTER_ENABLE_TIMEOUT_MS = 5000;
+
+    private boolean mIsHearingAidSupported;
+    private boolean mIsProfileReady;
+    private boolean mIsBleSupported;
+    private BluetoothHearingAid mService;
+    private BluetoothAdapter mBluetoothAdapter;
+    private BroadcastReceiver mIntentReceiver;
+
+    private static List<Integer> mValidConnectionStates = new ArrayList<Integer>(
+        Arrays.asList(BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED,
+                      BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING));
+
+    private List<BluetoothDevice> mIntentCallbackDeviceList;
+
+    public void setUp() throws Exception {
+        if (!isBleSupported()) return;
+        mIsBleSupported = true;
+
+        BluetoothManager manager = (BluetoothManager) mContext.getSystemService(
+                Context.BLUETOOTH_SERVICE);
+        mBluetoothAdapter = manager.getAdapter();
+        if (!mBluetoothAdapter.isEnabled()) {
+            mBluetoothAdapter.enable();
+            sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+            assertTrue(mBluetoothAdapter.isEnabled());
+        }
+
+        mIsProfileReady = false;
+        mService = null;
+        mIsHearingAidSupported = mBluetoothAdapter.getProfileProxy(getContext(),
+                                                  new HearingAidsServiceListener(),
+                                                  BluetoothProfile.HEARING_AID);
+        if (!mIsHearingAidSupported) return;
+
+        // Give the Service Proxy enough time to Connect
+        sleep(PROXY_CONNECTION_TIMEOUT_MS);
+    }
+
+    @Override
+    public void tearDown() {
+        if (!mIsBleSupported) return;
+
+        mBluetoothAdapter.disable();
+        sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+    }
+
+    /**
+     * Basic test case to make sure that Hearing Aid Profile Proxy can connect.
+     */
+    @MediumTest
+    public void test_getProxyServiceConnect() {
+        if (!(mIsBleSupported && mIsHearingAidSupported)) return;
+
+        assertTrue(mIsProfileReady);
+        assertNotNull(mService);
+    }
+
+    /**
+     * Basic test case to make sure that a fictional device is disconnected.
+     */
+    @MediumTest
+    public void test_getConnectionState() {
+        if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+                   (mService != null))) {
+            return;
+        }
+
+        // Create a dummy device
+        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("00:11:22:AA:BB:CC");
+        assertNotNull(device);
+
+        int connectionState = mService.getConnectionState(device);
+        // Dummy device should be disconnected
+        assertEquals(connectionState, BluetoothProfile.STATE_DISCONNECTED);
+    }
+
+    /**
+     * Basic test case to get the list of connected Hearing Aid devices.
+     */
+    @MediumTest
+    public void test_getConnectedDevices() {
+        if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+                   (mService != null))) {
+            return;
+        }
+
+        List<BluetoothDevice> deviceList;
+
+        deviceList = mService.getConnectedDevices();
+        Log.d(TAG, "getConnectedDevices(): size=" + deviceList.size());
+        for (BluetoothDevice device : deviceList) {
+            int connectionState = mService.getConnectionState(device);
+            checkValidConnectionState(connectionState);
+        }
+    }
+
+    /**
+     * Basic test case to get the list of matching Hearing Aid devices for each of the 4 connection
+     * states.
+     */
+    @MediumTest
+    public void test_getDevicesMatchingConnectionStates() {
+        if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+                   (mService != null))) {
+            return;
+        }
+
+        for (int connectionState : mValidConnectionStates) {
+            List<BluetoothDevice> deviceList;
+
+            deviceList = mService.getDevicesMatchingConnectionStates(new int[]{connectionState});
+            assertNotNull(deviceList);
+            Log.d(TAG, "getDevicesMatchingConnectionStates(" + connectionState + "): size="
+                  + deviceList.size());
+            checkDeviceListAndStates(deviceList, connectionState);
+        }
+    }
+
+    /**
+     * Test case to make sure that if the connection changed intent is called, the parameters and
+     * device are correct.
+     */
+    @MediumTest
+    public void test_getConnectionStateChangedIntent() {
+        if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+                   (mService != null))) {
+            return;
+        }
+
+        // Find out how many Hearing Aid bonded devices
+        List<BluetoothDevice> bondedDeviceList = new ArrayList();
+        int numDevices = 0;
+        for (int connectionState : mValidConnectionStates) {
+            List<BluetoothDevice> deviceList;
+
+            deviceList = mService.getDevicesMatchingConnectionStates(new int[]{connectionState});
+            bondedDeviceList.addAll(deviceList);
+            numDevices += deviceList.size();
+        }
+
+        if (numDevices <= 0) return;
+        Log.d(TAG, "Number Hearing Aids devices bonded=" + numDevices);
+
+        mIntentCallbackDeviceList = new ArrayList();
+
+        // Set up the Connection State Changed receiver
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+        mIntentReceiver = new HearingAidIntentReceiver();
+        mContext.registerReceiver(mIntentReceiver, filter);
+
+        Log.d(TAG, "test_getConnectionStateChangedIntent: disable adapter and wait");
+        mBluetoothAdapter.disable();
+        sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+
+        Log.d(TAG, "test_getConnectionStateChangedIntent: re-enable adapter and wait");
+        mBluetoothAdapter.enable();
+
+        int sanityCount = WAIT_FOR_INTENT_TIMEOUT_MS;
+        while ((numDevices != mIntentCallbackDeviceList.size()) && (sanityCount > 0)) {
+            final int SLEEP_QUANTUM_MS = 100;
+            sleep(SLEEP_QUANTUM_MS);
+            sanityCount -= SLEEP_QUANTUM_MS;
+        }
+
+        // Tear down
+        mContext.unregisterReceiver(mIntentReceiver);
+
+        Log.d(TAG, "test_getConnectionStateChangedIntent: number of bonded device="
+              + numDevices + ", mIntentCallbackDeviceList.size()="
+              + mIntentCallbackDeviceList.size());
+        for (BluetoothDevice device : mIntentCallbackDeviceList) {
+            assertTrue(bondedDeviceList.contains(device));
+        }
+    }
+
+    private final class HearingAidsServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mService = (BluetoothHearingAid) proxy;
+
+            mIsProfileReady = true;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mIsProfileReady = false;
+        }
+    }
+
+    private class HearingAidIntentReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
+                int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+                int previousState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
+                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+                Log.d(TAG,"HearingAidIntentReceiver.onReceive: device=" + device
+                      + ", state=" + state + ", previousState=" + previousState);
+
+                checkValidConnectionState(state);
+                checkValidConnectionState(previousState);
+
+                mIntentCallbackDeviceList.add(device);
+            }
+        }
+    }
+
+    private void checkDeviceListAndStates(List<BluetoothDevice> deviceList, int connectionState) {
+        Log.d(TAG, "checkDeviceListAndStates(): size=" + deviceList.size()
+              + ", connectionState=" + connectionState);
+        for (BluetoothDevice device : deviceList) {
+            int deviceConnectionState = mService.getConnectionState(device);
+            assertEquals("Mismatched connection state for " + device,
+                         connectionState, deviceConnectionState);
+        }
+    }
+
+    private void checkValidConnectionState(int connectionState) {
+        assertTrue(mValidConnectionStates.contains(connectionState));
+    }
+
+    // Returns whether offloaded scan batching is supported.
+    private boolean isBleBatchScanSupported() {
+        return mBluetoothAdapter.isOffloadedScanBatchingSupported();
+    }
+
+    // Check if Bluetooth LE feature is supported on DUT.
+    private boolean isBleSupported() {
+        return getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
+    }
+
+    private static void sleep(long t) {
+        try {
+            Thread.sleep(t);
+        } catch (InterruptedException e) {}
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
index 1d78ebb..df1bb16 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
@@ -52,6 +52,7 @@
                 0x02, 0x0A, (byte) 0xec, // tx power level
                 0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
                 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+                0x05, 0x14, 0x0c, 0x11, 0x0a, 0x11, // 16 bit service solicitation uuids
                 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
         };
 
@@ -118,6 +119,28 @@
     }
 
     @SmallTest
+    public void testsetServiceSolicitationUuidFilter() {
+        if (mFilterBuilder == null) return;
+
+        ScanFilter filter = mFilterBuilder.setServiceSolicitationUuid(
+                ParcelUuid.fromString(UUID1)).build();
+        assertEquals(UUID1, filter.getServiceSolicitationUuid().toString());
+        assertTrue("uuid filter fails", filter.matches(mScanResult));
+
+        filter = mFilterBuilder.setServiceSolicitationUuid(
+                ParcelUuid.fromString(UUID2)).build();
+        assertEquals(UUID2, filter.getServiceSolicitationUuid().toString());
+        assertFalse("uuid filter fails", filter.matches(mScanResult));
+
+        ParcelUuid mask = ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF");
+        filter = mFilterBuilder
+                .setServiceSolicitationUuid(ParcelUuid.fromString(UUID3), mask)
+                .build();
+        assertEquals(mask.toString(), filter.getServiceSolicitationUuidMask().toString());
+        assertTrue("uuid filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
     public void testsetServiceDataFilter() {
         if (mFilterBuilder == null) return;
 
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
index 30ad06f..0afd1ec 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
@@ -38,14 +38,23 @@
                 0x02, 0x0A, (byte) 0xec, // tx power level
                 0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
                 0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+                0x05, 0x14, 0x0c, 0x11, 0x0d, 0x11, // 16 bit service solicitation uuids
                 0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
         };
         ScanRecord data = TestUtils.parseScanRecord(scanRecord);
         assertEquals(0x1a, data.getAdvertiseFlags());
         ParcelUuid uuid1 = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
         ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+        ParcelUuid uuid3 = ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
+        ParcelUuid uuid4 = ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
         assertTrue(data.getServiceUuids().contains(uuid1));
         assertTrue(data.getServiceUuids().contains(uuid2));
+        assertFalse(data.getServiceUuids().contains(uuid3));
+        assertFalse(data.getServiceUuids().contains(uuid4));
+        assertFalse(data.getServiceSolicitationUuids().contains(uuid1));
+        assertFalse(data.getServiceSolicitationUuids().contains(uuid2));
+        assertTrue(data.getServiceSolicitationUuids().contains(uuid3));
+        assertTrue(data.getServiceSolicitationUuids().contains(uuid4));
 
         assertEquals("Ped", data.getDeviceName());
         assertEquals(-20, data.getTxPowerLevel());
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
index 41e8c71..fe1b64f 100644
--- a/tests/tests/car/AndroidManifest.xml
+++ b/tests/tests/car/AndroidManifest.xml
@@ -23,6 +23,12 @@
     <uses-permission android:name="android.car.permission.CAR_SPEED" />
     <application>
         <uses-library android:name="android.test.runner" />
+        <activity android:name=".drivingstate.DistractionOptimizedActivity">
+            <meta-data android:name="distractionOptimized" android:value="true"/>
+        </activity>
+        <activity android:name=".drivingstate.NonDistractionOptimizedActivity">
+            <meta-data android:name="distractionOptimized" android:value="false"/>
+        </activity>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 3f3c9a9..ec79572 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -82,50 +82,19 @@
        } catch (IllegalArgumentException expected) {
            // Expected.
        }
-   }
-
-    @Test
-    public void testSystemActivitiesAllowed() throws CarNotConnectedException {
-        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(
-                PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
-
-        for (PackageInfo info : packages) {
-            if (info.applicationInfo == null) {
-                continue;
-            }
-            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
-                    ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)) {
-
-                Bundle metaData = info.applicationInfo.metaData;
-                if (metaData == null || metaData.getInt(METADATA_ATTRIBUTE, 0) == 0) {
-                    continue;  // No car metadata, ignoring this app.
-                }
-
-                if (info.activities != null && info.activities.length > 0) {
-                    String activity = info.activities[0].name;
-                    String packageName = info.packageName;
-                    assertTrue("Failed for package: " + packageName + ", activity: " + activity,
-                            mCarPm.isActivityDistractionOptimized(packageName, activity));
-                }
-            }
-        }
     }
 
     @Test
-    @Ignore // Enable when b/120125891 is fixed
-    public void testServiceDistractionOptimized() throws Exception {
-        assertFalse(mCarPm.isServiceDistractionOptimized("com.basic.package", ""));
-        assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", "Any"));
-        assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", ""));
-        assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", null));
-
-        try {
-            mCarPm.isServiceDistractionOptimized(null, "Any");
-            fail();
-        } catch (IllegalArgumentException expected) {
-            // Expected.
-        }
+    public void testDistractionOptimizedActivityIsAllowed() throws CarNotConnectedException {
+        // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        assertTrue(mCarPm.isActivityDistractionOptimized("android.car.cts",
+                "android.car.cts.drivingstate.DistractionOptimizedActivity"));
     }
 
+    @Test
+    public void testNonDistractionOptimizedActivityNotAllowed() throws CarNotConnectedException {
+        // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        assertFalse(mCarPm.isActivityDistractionOptimized("android.car.cts",
+                "android.car.cts.drivingstate.NonDistractionOptimizedActivity"));
+    }
 }
diff --git a/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java b/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java
new file mode 100644
index 0000000..00440b6
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java
@@ -0,0 +1,6 @@
+package android.car.cts.drivingstate;
+
+import android.app.Activity;
+
+public class DistractionOptimizedActivity extends Activity {
+}
\ No newline at end of file
diff --git a/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java b/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java
new file mode 100644
index 0000000..0c75a3a
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java
@@ -0,0 +1,6 @@
+package android.car.cts.drivingstate;
+
+import android.app.Activity;
+
+public class NonDistractionOptimizedActivity extends Activity {
+}
diff --git a/tests/tests/content/jni/NativeCursorWindow.c b/tests/tests/content/jni/NativeCursorWindow.c
index a2fb92a..95342e6 100644
--- a/tests/tests/content/jni/NativeCursorWindow.c
+++ b/tests/tests/content/jni/NativeCursorWindow.c
@@ -69,7 +69,7 @@
 JNIEXPORT jint JNICALL
 Java_android_content_cts_CursorWindowContentProvider_makeNativeCursorWindowFd(JNIEnv *env, jclass clazz,
 jint offset, jint size, jboolean isBlob) {
-    int fd = open("/dev/ashmem", O_RDWR);
+    int fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
     ioctl(fd, ASHMEM_SET_NAME, "Fake CursorWindow");
 
     ioctl(fd, ASHMEM_SET_SIZE, 1024);
diff --git a/tests/tests/content/res/values/styles.xml b/tests/tests/content/res/values/styles.xml
index 91191cf..7da5c5e 100644
--- a/tests/tests/content/res/values/styles.xml
+++ b/tests/tests/content/res/values/styles.xml
@@ -39,6 +39,21 @@
         <item name="typeUndefined">@null</item>
     </style>
 
+    <style name="StyleA" parent="StyleB">
+        <item name="type1">true</item>
+    </style>
+    <style name="StyleB" parent="StyleC">
+        <item name="type1">false</item>
+        <item name="type2">false</item>
+        <item name="type4">@color/testcolor1</item>
+    </style>
+
+    <style name="StyleC">
+        <item name="type1">false</item>
+        <item name="type2">true</item>
+        <item name="type3">#ff0000ff</item>
+    </style>
+
     <style name="TextViewWithoutColorAndAppearance">
         <item name="android:textSize">18sp</item>
     </style>
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
new file mode 100644
index 0000000..a8919b9
--- /dev/null
+++ b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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.content.om.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static android.content.om.OverlayInfo.CREATOR;
+
+import org.junit.Assert;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+
+
+/**
+ * Verifies the member variables inside {@link OverlayInfo}
+ */
+@RunWith(AndroidJUnit4.class)
+public class OverlayInfoTest {
+
+    private static final String PKG_NAME = "source package name";
+    private static final String TARGET_PKG_NAME = "target package name";
+    private static final String CATEGORY = "sample category";
+    private static final String BASE_CODE_PATH = "base code path";
+
+    @Test
+    public void testEnsureValidState() {
+        OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+            0, 0, 0, true);
+        assertNotNull(info);
+    }
+
+    @Test
+    public void testEnsureValidState_fail() {
+        try {
+            OverlayInfo info = new OverlayInfo(null, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+                0, 0, 0, true);
+            fail("Should throw exception.");
+        } catch (IllegalArgumentException e) {
+            // no op, working as intended.
+        }
+
+        try {
+            OverlayInfo info = new OverlayInfo(PKG_NAME, null, CATEGORY, BASE_CODE_PATH,
+                0, 0, 0, true);
+            fail("Should throw exception.");
+        } catch (IllegalArgumentException e) {
+            // no op, working as intended.
+        }
+
+        try {
+            OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, null,
+                0, 0, 0, true);
+            fail("Should throw exception.");
+        } catch (IllegalArgumentException e) {
+            // no op, working as intended.
+        }
+    }
+
+    @Test
+    public void testWriteToParcel() {
+        OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+            0, 0, 0, true);
+        Parcel p = Parcel.obtain();
+        info.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        OverlayInfo copyInfo = CREATOR.createFromParcel(p);
+        p.recycle();
+
+        assertEquals(info.packageName, copyInfo.packageName);
+        assertEquals(info.targetPackageName, copyInfo.targetPackageName);
+        assertEquals(info.category, copyInfo.category);
+        assertEquals(info.baseCodePath, copyInfo.baseCodePath);
+        assertEquals(info.state, copyInfo.state);
+        assertEquals(info.userId, copyInfo.userId);
+        assertEquals(info.priority, copyInfo.priority);
+        assertEquals(info.isStatic, copyInfo.isStatic);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
new file mode 100644
index 0000000..bda44a2
--- /dev/null
+++ b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.content.om.cts;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.times;
+
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayManager;
+import android.content.om.OverlayInfo;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * This only tests the client API implementation of the OverlayManager
+ * and not the service implementation.
+ */
+@RunWith(AndroidJUnit4.class)
+public class OverlayManagerTest {
+
+    private OverlayManager mManager;
+    @Mock
+    private IOverlayManager mMockService;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        mManager = new OverlayManager(context, mMockService);
+    }
+
+    @Test
+    public void testSetEnabledExclusiveInCategory() throws Exception {
+        String packageName = "overlay source package name";
+        int userId = 10;
+        verify(mMockService, times(0)).setEnabledExclusiveInCategory(packageName, userId);
+        mManager.setEnabledExclusiveInCategory(packageName, userId);
+        verify(mMockService, times(1)).setEnabledExclusiveInCategory(packageName, userId);
+    }
+
+    @Test
+    public void testGetOverlayInfosForTarget() throws Exception {
+        String targetPackageName = "overlay target package name";
+        int userId = 10;
+        verify(mMockService, times(0)).getOverlayInfosForTarget(targetPackageName, userId);
+        mManager.getOverlayInfosForTarget(targetPackageName, userId);
+        verify(mMockService, times(1)).getOverlayInfosForTarget(targetPackageName, userId);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
index a21039e..29c533c 100644
--- a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
@@ -36,6 +36,8 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Parcel;
+import android.os.Process;
+import android.os.UserHandle;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.StringBuilderPrinter;
@@ -153,14 +155,14 @@
         // The application "com.android.cts.stub" does not have any attributes set
         mApplicationInfo = getContext().getPackageManager().getApplicationInfo(
                 SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, 0);
+        int currentUserId = Process.myUserHandle().getIdentifier();
 
         assertNull(mApplicationInfo.className);
         assertNull(mApplicationInfo.permission);
         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.packageName);
         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.processName);
         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.taskAffinity);
-        assertTrue(FIRST_APPLICATION_UID <= mApplicationInfo.uid
-                && LAST_APPLICATION_UID >= mApplicationInfo.uid);
+        assertTrue(UserHandle.isApp(mApplicationInfo.uid));
         assertEquals(0, mApplicationInfo.theme);
         assertEquals(0, mApplicationInfo.requiresSmallestWidthDp);
         assertEquals(0, mApplicationInfo.compatibleWidthLimitDp);
@@ -169,11 +171,11 @@
         assertEquals(mApplicationInfo.sourceDir, mApplicationInfo.publicSourceDir);
         assertNull(mApplicationInfo.splitSourceDirs);
         assertArrayEquals(mApplicationInfo.splitSourceDirs, mApplicationInfo.splitPublicSourceDirs);
-        assertEquals("/data/user/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+        assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
                 mApplicationInfo.dataDir);
-        assertEquals("/data/user_de/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+        assertEquals("/data/user_de/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
                 mApplicationInfo.deviceProtectedDataDir);
-        assertEquals("/data/user/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+        assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
                 mApplicationInfo.credentialProtectedDataDir);
         assertNull(mApplicationInfo.sharedLibraryFiles);
         assertTrue(mApplicationInfo.enabled);
diff --git a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
index 03788b5..a68445f 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
@@ -70,6 +70,10 @@
         mResources = getContext().getResources();
     }
 
+    public void testIdNull() {
+        assertEquals(0, Resources.ID_NULL);
+    }
+
     public void testResources() {
         final AssetManager am = new AssetManager();
         final Configuration cfg = new Configuration();
diff --git a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
index f27f06c..38a6a5b 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.content.cts.R;
 import android.content.cts.util.XmlUtils;
 import android.content.pm.ActivityInfo;
@@ -32,6 +30,8 @@
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 
 public class TypedArrayTest extends AndroidTestCase {
@@ -72,6 +72,19 @@
         mTypedArray.recycle();
     }
 
+    public void testSourceStyleResourceId() {
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                R.style.StyleA, R.styleable.style1);
+
+        assertEquals(R.style.StyleA, t.getSourceStyleResourceId(R.styleable.style1_type1, 0));
+        assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type2, 0));
+        assertEquals(R.style.StyleC, t.getSourceStyleResourceId(R.styleable.style1_type3, 0));
+        assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type4, 0));
+        assertEquals(0, t.getSourceStyleResourceId(R.styleable.style1_type5, 0));
+
+        t.recycle();
+    }
+
     public void testGetType() {
         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
                 R.style.Whatever, R.styleable.style1);
diff --git a/tests/tests/database/AndroidTest.xml b/tests/tests/database/AndroidTest.xml
index 1a53a10..9c53d2d 100644
--- a/tests/tests/database/AndroidTest.xml
+++ b/tests/tests/database/AndroidTest.xml
@@ -20,6 +20,7 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsDatabaseTestCases.apk" />
+        <option name="test-file-name" value="CtsProviderApp.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.database.cts" />
diff --git a/tests/tests/database/apps/Android.bp b/tests/tests/database/apps/Android.bp
new file mode 100644
index 0000000..9953fc1
--- /dev/null
+++ b/tests/tests/database/apps/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 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.
+
+android_test {
+  name: "CtsProviderApp",
+  sdk_version: "test_current",
+
+  srcs: [
+    "src/**/*.java"
+  ],
+
+  test_suites: [
+    "cts",
+    "vts",
+    "general-tests",
+  ]
+}
\ No newline at end of file
diff --git a/tests/tests/database/apps/AndroidManifest.xml b/tests/tests/database/apps/AndroidManifest.xml
new file mode 100644
index 0000000..a199a8f
--- /dev/null
+++ b/tests/tests/database/apps/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.providerapp">
+
+    <application>
+        <provider android:name=".DummyProvider"
+                android:authorities="com.android.cts.providerapp"
+                android:exported="true">
+        </provider>
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java b/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java
new file mode 100644
index 0000000..8c06f05
--- /dev/null
+++ b/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.providerapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class DummyProvider extends ContentProvider {
+    private static final String TAG = DummyProvider.class.getName();
+
+    private static final String AUTHORITY = "com.android.cts.providerapp";
+    private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+    private static final Uri TEST_URI1 = Uri.withAppendedPath(CONTENT_URI, "test1");
+    private static final Uri TEST_URI2 = Uri.withAppendedPath(CONTENT_URI, "test2");
+
+    private static final String CALL_NOTIFY = "notify";
+
+    @Override
+    public boolean onCreate() {
+        Log.d(TAG, "onCreate");
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        Log.d(TAG, "query uri: " + uri);
+        if (!CONTENT_URI.equals(uri)) {
+            throw new UnsupportedOperationException();
+        }
+
+        final MatrixCursor cursor = new MatrixCursor(new String[] {
+                BaseColumns._ID, BaseColumns._COUNT
+        }, 2);
+        cursor.addRow(new Integer[] {100, 2});
+        cursor.addRow(new Integer[] {101, 3});
+        cursor.setNotificationUris(getContext().getContentResolver(),
+                Arrays.asList(TEST_URI1, TEST_URI2));
+        return cursor;
+    }
+
+    @Override
+    public Bundle call(String method, String arg, Bundle extras) {
+        Log.d(TAG, "call method: " + method + ", arg: " + arg);
+        if (!CALL_NOTIFY.equals(method)) {
+            throw new UnsupportedOperationException();
+        }
+
+        switch (arg) {
+            case "1":
+                getContext().getContentResolver().notifyChange(TEST_URI1, null);
+                break;
+            case "2":
+                getContext().getContentResolver().notifyChange(TEST_URI2, null);
+                break;
+            default:
+                throw new UnsupportedOperationException();
+        }
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection,
+            String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index ba2f1fd..9a4ba50 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -20,6 +20,7 @@
 import android.database.AbstractCursor;
 import android.database.CharArrayBuffer;
 import android.database.ContentObserver;
+import android.database.Cursor;
 import android.database.CursorIndexOutOfBoundsException;
 import android.database.CursorWindow;
 import android.database.DataSetObserver;
@@ -29,9 +30,15 @@
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 
+import org.junit.Assert;
+
 import java.io.File;
+import java.util.Arrays;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Test {@link AbstractCursor}.
@@ -52,6 +59,9 @@
     private SQLiteDatabase mDatabase;
     private File mDatabaseFile;
     private AbstractCursor mDatabaseCursor;
+    private Context mContext;
+
+    private static final long ON_CHANGE_TIMEOUT_MS = 5000;
 
     @Override
     protected void setUp() throws Exception {
@@ -60,6 +70,7 @@
         setupDatabase();
         ArrayList<ArrayList> list = createTestList(ROW_MAX, COLUMN_NAMES.length);
         mTestAbstractCursor = new TestAbstractCursor(COLUMN_NAMES, list);
+        mContext = getInstrumentation().getContext();
     }
 
     @Override
@@ -139,6 +150,47 @@
                 testUri);
     }
 
+    public void testSetNotificationUris_selfNotify() throws Exception {
+        final Uri testUri1 = Settings.System.getUriFor(Settings.System.TIME_12_24);
+        final Uri testUri2 = Settings.Global.getUriFor(
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+        mDatabaseCursor.setNotificationUris(mContext.getContentResolver(),
+                Arrays.asList(testUri1, testUri2));
+        final MockContentObserver observer = new MockContentObserver();
+        mDatabaseCursor.registerContentObserver(observer);
+
+        mContext.getContentResolver().notifyChange(testUri1, null);
+        observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+        observer.resetOnChangeWatch();
+        mContext.getContentResolver().notifyChange(testUri2, null);
+        observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+    }
+
+    public void testSetNotificationsUris() throws Exception {
+        final Uri queryUri = Uri.parse("content://com.android.cts.providerapp");
+        try (Cursor cursor = mContext.getContentResolver().query(queryUri, null, null, null)) {
+            final MockContentObserver observer = new MockContentObserver();
+            cursor.registerContentObserver(observer);
+
+            mContext.getContentResolver().call(queryUri, "notify", "1", null);
+            observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+            observer.resetOnChangeWatch();
+            mContext.getContentResolver().call(queryUri, "notify", "2", null);
+            observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+        }
+    }
+
+    public void testGetNotificationUris() throws Exception {
+        final Uri[] notificationUris = new Uri[] {
+                Settings.Global.getUriFor(Settings.Global.MODE_RINGER),
+                Settings.Global.getUriFor(Settings.Global.BOOT_COUNT)
+        };
+        mDatabaseCursor.setNotificationUris(mContext.getContentResolver(),
+                Arrays.asList(notificationUris));
+        final List<Uri> actualNotificationUris = mDatabaseCursor.getNotificationUris();
+        Assert.assertArrayEquals(notificationUris, actualNotificationUris.toArray(new Uri[0]));
+    }
+
     public void testRespond() {
         Bundle b = new Bundle();
         Bundle bundle = mDatabaseCursor.respond(b);
@@ -159,14 +211,8 @@
     public void testOnChange() throws InterruptedException {
         MockContentObserver mock = new MockContentObserver();
         mTestAbstractCursor.registerContentObserver(mock);
-        assertFalse(mock.hadCalledOnChange());
         mTestAbstractCursor.onChange(true);
-        synchronized(mLockObj) {
-            if ( !mock.hadCalledOnChange() ) {
-                mLockObj.wait(5000);
-            }
-        }
-        assertTrue(mock.hadCalledOnChange());
+        mock.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
     }
 
     public void testOnMove() {
@@ -588,19 +634,18 @@
     }
 
     private class MockContentObserver extends ContentObserver {
-        public boolean mHadCalledOnChange;
+        private CountDownLatch mCountDownLatch;
 
         public MockContentObserver() {
             super(null);
+
+            mCountDownLatch = new CountDownLatch(1);
         }
 
         @Override
         public void onChange(boolean selfChange) {
             super.onChange(selfChange);
-            mHadCalledOnChange = true;
-            synchronized(mLockObj) {
-                mLockObj.notify();
-            }
+            mCountDownLatch.countDown();
         }
 
         @Override
@@ -608,8 +653,14 @@
             return true;
         }
 
-        public boolean hadCalledOnChange() {
-            return mHadCalledOnChange;
+        public void resetOnChangeWatch() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        public void waitForOnChange(long timeoutMs) throws InterruptedException {
+            if (!mCountDownLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
+                fail("Timed out waiting for onChange() to get called");
+            }
         }
     }
 
diff --git a/tests/tests/display/src/android/display/cts/BrightnessTest.java b/tests/tests/display/src/android/display/cts/BrightnessTest.java
index 6b01df2..a4e3aa3 100644
--- a/tests/tests/display/src/android/display/cts/BrightnessTest.java
+++ b/tests/tests/display/src/android/display/cts/BrightnessTest.java
@@ -19,16 +19,19 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.Manifest;
 import android.app.UiAutomation;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.hardware.display.BrightnessChangeEvent;
 import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.BrightnessCorrection;
 import android.hardware.display.DisplayManager;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
@@ -210,10 +213,20 @@
         BrightnessConfiguration config =
                 new BrightnessConfiguration.Builder(
                         new float[]{0.0f, 1000.0f},new float[]{20.0f, 500.0f})
+                        .addCorrectionByCategory(ApplicationInfo.CATEGORY_IMAGE,
+                                BrightnessCorrection.createScaleAndTranslateLog(0.80f, 0.2f))
+                        .addCorrectionByPackageName("some.package.name",
+                                BrightnessCorrection.createScaleAndTranslateLog(0.70f, 0.1f))
                         .setDescription("some test").build();
         mDisplayManager.setBrightnessConfiguration(config);
         BrightnessConfiguration returnedConfig = mDisplayManager.getBrightnessConfiguration();
         assertEquals(config, returnedConfig);
+        assertEquals(config.getCorrectionByCategory(ApplicationInfo.CATEGORY_IMAGE),
+                BrightnessCorrection.createScaleAndTranslateLog(0.80f, 0.2f));
+        assertEquals(config.getCorrectionByPackageName("some.package.name"),
+                BrightnessCorrection.createScaleAndTranslateLog(0.70f, 0.1f));
+        assertNull(config.getCorrectionByCategory(ApplicationInfo.CATEGORY_GAME));
+        assertNull(config.getCorrectionByPackageName("someother.package.name"));
 
         // After clearing the curve we should get back the default curve.
         mDisplayManager.setBrightnessConfiguration(null);
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index cb8e7cd..8283d61 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -26,6 +26,7 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager;
@@ -192,7 +193,7 @@
         HdrCapabilities cap = display.getHdrCapabilities();
         int[] hdrTypes = cap.getSupportedHdrTypes();
         for (int type : hdrTypes) {
-            assertTrue(type >= 1 && type <= 3);
+            assertTrue(type >= 1 && type <= 4);
         }
         assertFalse(cap.getDesiredMaxLuminance() < -1.0f);
         assertFalse(cap.getDesiredMinLuminance() < -1.0f);
@@ -372,6 +373,22 @@
     }
 
     /**
+     * Verify that getColorSpace method returns the expected color space of the display.
+     */
+    @Test
+    public void testGetPreferredWideGamutColorSpace() {
+        final Display defaultDisplay = mWindowManager.getDefaultDisplay();
+        final ColorSpace colorSpace = defaultDisplay.getPreferredWideGamutColorSpace();
+
+        if (defaultDisplay.isWideColorGamut()) {
+            assertFalse(colorSpace.isSrgb());
+            assertTrue(colorSpace.isWideGamut());
+        } else {
+            assertNull(colorSpace);
+        }
+    }
+
+    /**
      * Used to force mode changes on a display.
      * <p>
      * Note that due to limitations of the Presentation class, the modes must have the same size
diff --git a/tests/tests/dynamic_linker/Android.mk b/tests/tests/dynamic_linker/Android.mk
index ef122ca..be1e782 100644
--- a/tests/tests/dynamic_linker/Android.mk
+++ b/tests/tests/dynamic_linker/Android.mk
@@ -43,6 +43,19 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, .)
 LOCAL_MULTILIB := both
 LOCAL_JNI_SHARED_LIBRARIES := libdynamiclinker_native_lib_a libdynamiclinker_native_lib_b
+LOCAL_MANIFEST_FILE := AndroidManifest_27.xml
+LOCAL_PACKAGE_NAME := CtsDynamicLinkerTestCases27
+LOCAL_SDK_VERSION := current
+LOCAL_COMPATIBILITY_SUITE := cts vts
+include $(BUILD_CTS_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_SRC_FILES := $(call all-java-files-under, .)
+LOCAL_MULTILIB := both
+LOCAL_JNI_SHARED_LIBRARIES := libdynamiclinker_native_lib_a libdynamiclinker_native_lib_b
 LOCAL_MANIFEST_FILE := AndroidManifest.xml
 LOCAL_PACKAGE_NAME := CtsDynamicLinkerTestCases
 LOCAL_SDK_VERSION := current
diff --git a/tests/tests/dynamic_linker/AndroidManifest.xml b/tests/tests/dynamic_linker/AndroidManifest.xml
index db8099e..7a9166d 100644
--- a/tests/tests/dynamic_linker/AndroidManifest.xml
+++ b/tests/tests/dynamic_linker/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.dynamiclinker">
 
-    <application android:extractNativeLibs="false">
+    <application>
         <uses-library android:name="android.test.runner" />
     </application>
     <instrumentation
diff --git a/tests/tests/dynamic_linker/AndroidManifest_27.xml b/tests/tests/dynamic_linker/AndroidManifest_27.xml
new file mode 100644
index 0000000..eae214a
--- /dev/null
+++ b/tests/tests/dynamic_linker/AndroidManifest_27.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.dynamiclinker27">
+    <!-- Before 27, extractNativeLibs is default to true. -->
+    <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27" />
+
+    <application android:extractNativeLibs="false">
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation
+        android:targetPackage="com.android.dynamiclinker27"
+        android:name="android.support.test.runner.AndroidJUnitRunner" />
+</manifest>
diff --git a/tests/tests/dynamic_linker/AndroidTest.xml b/tests/tests/dynamic_linker/AndroidTest.xml
index 483ae03..a043e15 100644
--- a/tests/tests/dynamic_linker/AndroidTest.xml
+++ b/tests/tests/dynamic_linker/AndroidTest.xml
@@ -18,9 +18,13 @@
     <option name="config-descriptor:metadata" key="component" value="bionic" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsDynamicLinkerTestCases27.apk" />
         <option name="test-file-name" value="CtsDynamicLinkerTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.dynamiclinker27" />
+    </test>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.dynamiclinker" />
     </test>
 </configuration>
diff --git a/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java b/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
index f0d7c4b..a23bc50 100644
--- a/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
+++ b/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
@@ -19,6 +19,8 @@
 import junit.framework.TestCase;
 import android.support.test.InstrumentationRegistry;
 
+import java.io.File;
+
 public class DynamicLinkerTest extends TestCase {
 
   private native int functionA();
@@ -47,4 +49,9 @@
     assertEquals(1, functionB());
   }
 
+  public void testNativeLibraryNotExtracted() {
+    File dir = new File(InstrumentationRegistry.getContext().getApplicationInfo().nativeLibraryDir);
+    assertTrue(dir.isDirectory());
+    assertEquals(0, dir.list().length);
+  }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
index c24086a..f5f1560 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
@@ -85,13 +85,13 @@
         b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGBA_F16, true, sRGB);
         cs = b.getColorSpace();
         assertNotNull(cs);
-        assertSame(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB), cs);
+        assertSame(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), cs);
 
         b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGBA_F16, true,
                 ColorSpace.get(ColorSpace.Named.ADOBE_RGB));
         cs = b.getColorSpace();
         assertNotNull(cs);
-        assertSame(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB), cs);
+        assertSame(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), cs);
 
         b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGB_565, true, sRGB);
         cs = b.getColorSpace();
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 69bb828..f43df11 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -580,6 +580,13 @@
         mBitmap.eraseColor(0);
     }
 
+    @Test(expected = IllegalStateException.class)
+    public void testEraseColorLongOnRecycled() {
+        mBitmap.recycle();
+
+        mBitmap.eraseColor(Color.pack(0));
+    }
+
     @Test(expected=IllegalStateException.class)
     public void testEraseColorOnImmutable() {
         mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
@@ -588,6 +595,14 @@
         mBitmap.eraseColor(0);
     }
 
+    @Test(expected = IllegalStateException.class)
+    public void testEraseColorLongOnImmutable() {
+        mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
+
+        //abnormal case: bitmap is immutable
+        mBitmap.eraseColor(Color.pack(0));
+    }
+
     @Test
     public void testEraseColor() {
         // normal case
@@ -597,6 +612,109 @@
         assertEquals(0xffff0000, mBitmap.getPixel(50, 50));
     }
 
+    private static class ARGB {
+        public float alpha;
+        public float red;
+        public float green;
+        public float blue;
+        ARGB(float alpha, float red, float green, float blue) {
+            this.alpha = alpha;
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+        }
+    };
+
+    @Test
+    public void testEraseColorLong() {
+        // normal case
+        for (Config config : new Config[]{Config.ARGB_8888, Config.RGB_565, Config.RGBA_F16}) {
+            mBitmap = Bitmap.createBitmap(100, 100, config);
+            // pack SRGB colors into ColorLongs.
+            for (int color : new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.BLACK,
+                    Color.WHITE, Color.TRANSPARENT }) {
+                if (config.equals(Config.RGB_565) && Float.compare(Color.alpha(color), 1.0f) != 0) {
+                    // 565 doesn't support alpha.
+                    continue;
+                }
+                mBitmap.eraseColor(Color.pack(color));
+                // The Bitmap is either SRGB or SRGBLinear (F16). getPixel(), which retrieves the
+                // color in SRGB, should match exactly.
+                ColorUtils.verifyColor("Config " + config + " mismatch at 10, 10 ",
+                        color, mBitmap.getPixel(10, 10), 0);
+                ColorUtils.verifyColor("Config " + config + " mismatch at 50, 50 ",
+                        color, mBitmap.getPixel(50, 50), 0);
+            }
+
+            // Use arbitrary colors in various ColorSpaces. getPixel() should approximately match
+            // the SRGB version of the color.
+            for (ARGB color : new ARGB[]{ new ARGB(1.0f, .5f, .5f, .5f),
+                                          new ARGB(1.0f, .3f, .6f, .9f),
+                                          new ARGB(0.5f, .2f, .8f, .7f) }) {
+                if (config.equals(Config.RGB_565) && Float.compare(color.alpha, 1.0f) != 0) {
+                    continue;
+                }
+                int srgbColor = Color.argb(color.alpha, color.red, color.green, color.blue);
+                for (ColorSpace.Named e : ColorSpace.Named.values()) {
+                    ColorSpace cs = ColorSpace.get(e);
+                    if (cs.getModel() != ColorSpace.Model.RGB) {
+                        continue;
+                    }
+                    if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
+                        continue;
+                    }
+                    long longColor = Color.convert(srgbColor, cs);
+                    mBitmap.eraseColor(longColor);
+                    // These tolerances were chosen by trial and error. It is expected that
+                    // some conversions do not round-trip perfectly.
+                    int tolerance = 1;
+                    if (config.equals(Config.RGB_565)) {
+                        tolerance = 4;
+                    } else if (cs.equals(ColorSpace.get(ColorSpace.Named.SMPTE_C))) {
+                        tolerance = 3;
+                    }
+
+                    ColorUtils.verifyColor("Config " + config + ", ColorSpace " + cs
+                            + ", mismatch at 10, 10 ", srgbColor, mBitmap.getPixel(10, 10),
+                            tolerance);
+                    ColorUtils.verifyColor("Config " + config + ", ColorSpace " + cs
+                            + ", mismatch at 50, 50 ", srgbColor, mBitmap.getPixel(50, 50),
+                            tolerance);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testEraseColorOnP3() {
+        // Use a ColorLong with a different ColorSpace than the Bitmap. getPixel() should
+        // approximately match the SRGB version of the color.
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888, true,
+                ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        int srgbColor = Color.argb(.5f, .3f, .6f, .7f);
+        long acesColor = Color.convert(srgbColor, ColorSpace.get(ColorSpace.Named.ACES));
+        mBitmap.eraseColor(acesColor);
+        ColorUtils.verifyColor("Mismatch at 15, 15", srgbColor, mBitmap.getPixel(15, 15), 1);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testEraseColorXYZ() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.eraseColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testEraseColorLAB() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.eraseColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testEraseColorUnknown() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.eraseColor(-1L);
+    }
+
     @Test(expected=IllegalStateException.class)
     public void testExtractAlphaFromRecycled() {
         mBitmap.recycle();
@@ -1495,6 +1613,12 @@
     }
 
     @Test(expected = IllegalStateException.class)
+    public void testHardwareEraseColorLong() {
+        Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, HARDWARE_OPTIONS);
+        bitmap.eraseColor(Color.pack(0));
+    }
+
+    @Test(expected = IllegalStateException.class)
     public void testHardwareCopyPixelsToBuffer() {
         Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, HARDWARE_OPTIONS);
         ByteBuffer byteBuf = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
diff --git a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
index 01ba9e5..ad72765b 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
@@ -22,8 +22,6 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
 
 import android.graphics.ColorSpace;
 import android.support.test.filters.SmallTest;
@@ -71,9 +69,6 @@
 
     private static final DoubleUnaryOperator sIdentity = DoubleUnaryOperator.identity();
 
-    @Rule
-    public ExpectedException mExpectedException = ExpectedException.none();
-
     @Test
     public void testNamedColorSpaces() {
         for (ColorSpace.Named named : ColorSpace.Named.values()) {
@@ -318,17 +313,19 @@
 
     @Test
     public void testIsSRGB() {
-        assertTrue(ColorSpace.get(ColorSpace.Named.SRGB).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_SRGB).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.DISPLAY_P3).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.CIE_LAB).isSrgb());
-        assertFalse(ColorSpace.get(ColorSpace.Named.CIE_XYZ).isSrgb());
+        for (ColorSpace.Named e : ColorSpace.Named.values()) {
+            ColorSpace colorSpace = ColorSpace.get(e);
+            if (e == ColorSpace.Named.SRGB) {
+                assertTrue(colorSpace.isSrgb());
+            } else {
+                assertFalse("Incorrectly treating " + colorSpace + " as SRGB!",
+                            colorSpace.isSrgb());
+            }
+        }
 
-        ColorSpace.Rgb cs = new ColorSpace.Rgb("My sRGB", SRGB_TO_XYZ,
+        ColorSpace.Rgb cs = new ColorSpace.Rgb("Almost sRGB", SRGB_TO_XYZ,
                 x -> Math.pow(x, 1.0f / 2.2f), x -> Math.pow(x, 2.2f));
-        assertTrue(cs.isSrgb());
+        assertFalse(cs.isSrgb());
     }
 
     @Test
@@ -615,31 +612,6 @@
     }
 
     @Test
-    public void testSinglePointAdaptation() {
-        float[] illumD65xyY = Arrays.copyOf(ColorSpace.ILLUMINANT_D65,
-                ColorSpace.ILLUMINANT_D65.length);
-        float[] illumD50xyY = Arrays.copyOf(ColorSpace.ILLUMINANT_D50,
-                ColorSpace.ILLUMINANT_D50.length);
-
-        final float[] catXyz = ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
-                illumD65xyY, illumD50xyY);
-
-        // Ensure the original arguments were not modified
-        assertArrayEquals(illumD65xyY, ColorSpace.ILLUMINANT_D65, 0);
-        assertArrayEquals(illumD50xyY, ColorSpace.ILLUMINANT_D50, 0);
-
-        // Verify results. This reference data has been cross-checked with
-        // http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
-        final float[] illumD65ToIllumD50Xyz = {
-             1.0478525f,  0.0295722f, -0.0092367f,
-             0.0229074f,  0.9904668f,  0.0150463f,
-            -0.0501464f, -0.0170567f,  0.7520621f
-        };
-
-        assertArrayEquals(catXyz, illumD65ToIllumD50Xyz, 1e-7f);
-    }
-
-    @Test
     public void testImplicitSRGBConnector() {
         ColorSpace.Connector connector1 = ColorSpace.connect(
                 ColorSpace.get(ColorSpace.Named.DCI_P3));
@@ -813,19 +785,6 @@
                         1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4)));
     }
 
-    @Test
-    public void testCctToIlluminantdXyz() {
-        assertArrayEquals(ColorSpace.cctToIlluminantdXyz(5000),
-                xyYToXyz(ColorSpace.ILLUMINANT_D50), 0.01f);
-        assertArrayEquals(ColorSpace.cctToIlluminantdXyz(7500),
-                xyYToXyz(ColorSpace.ILLUMINANT_D75), 0.01f);
-    }
-
-    @Test
-    public void testCctToIlluminantdXyzErrors() {
-        mExpectedException.expect(IllegalArgumentException.class);
-        ColorSpace.cctToIlluminantdXyz(0);
-    }
 
     @SuppressWarnings("SameParameterValue")
     private static void assertArrayNotEquals(float[] a, float[] b, float eps) {
@@ -843,12 +802,4 @@
             }
         }
     }
-
-    /**
-     * Convenience function copied from android.graphics.ColorSpace
-     */
-    private static float[] xyYToXyz(float[] xyY) {
-        return new float[] { xyY[0] / xyY[1], 1.0f, (1 - xyY[0] - xyY[1]) / xyY[1] };
-    }
-
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
index adb7c1b..a2c0cd6 100644
--- a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
@@ -366,6 +366,14 @@
     }
 
     @Test
+    public void testConvertToBT709() {
+        int sRgb = Color.argb(1.0f, 0.5f, 0.5f, 0.5f);
+        long bt709 = Color.convert(sRgb, ColorSpace.get(Named.BT709));
+
+        assertEquals(ColorSpace.get(Named.BT709), Color.colorSpace(bt709));
+    }
+
+    @Test
     public void testConvertColorInt() {
         long color = convert(0xffff8000, ColorSpace.get(Named.ADOBE_RGB));
 
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
index 0cbf5d4..786f933 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
@@ -1693,13 +1693,16 @@
         for (int resId : new int[] { R.drawable.png_test, R.raw.f16 }) {
             Bitmap normal = null;
             try {
-                normal = ImageDecoder.decodeBitmap(f.apply(resId));
+                normal = ImageDecoder.decodeBitmap(f.apply(resId), ((decoder, info, source) -> {
+                    decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
+                }));
             } catch (IOException e) {
                 fail("Failed with exception " + e);
             }
             assertNotNull(normal);
             int normalByteCount = normal.getAllocationByteCount();
-            for (int allocator : ALLOCATORS) {
+            int[] allocators = { ImageDecoder.ALLOCATOR_HARDWARE, ImageDecoder.ALLOCATOR_DEFAULT };
+            for (int allocator : allocators) {
                 l.allocator = allocator;
                 Bitmap test = null;
                 try {
@@ -1710,33 +1713,13 @@
                 assertNotNull(test);
                 int byteCount = test.getAllocationByteCount();
 
-                if (allocator == ImageDecoder.ALLOCATOR_HARDWARE
-                        || allocator == ImageDecoder.ALLOCATOR_DEFAULT) {
-                    if (resId == R.drawable.png_test) {
-                        // We do not support 565 in HARDWARE, so no RAM savings
-                        // are possible.
-                        assertEquals(normalByteCount, byteCount);
-                    } else { // R.raw.f16
-                        // This image defaults to F16. MEMORY_POLICY_LOW_RAM
-                        // forces "test" to decode to 8888. But if the device
-                        // does not support F16 in HARDWARE, "normal" is also
-                        // 8888. Its Config is HARDWARE either way, but we can
-                        // detect its underlying pixel format by checking the
-                        // ColorSpace, which is always LINEAR_EXTENDED_SRGB for
-                        // F16.
-                        if (normal.getColorSpace().equals(
-                                    ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB))) {
-                            // F16. "test" should be smaller.
-                            assertTrue(byteCount < normalByteCount);
-                        } else {
-                            // 8888. No RAM savings possible.
-                            assertEquals(normalByteCount, byteCount);
-                        }
-                    }
-                } else {
-                    // Not decoding to HARDWARE, but |normal| was. As such this should always
-                    // succeed in being smaller, as software will decode to 565 in this case.
-                    // This will always be less than whatever HARDWARE supports.
+                if (resId == R.drawable.png_test) {
+                    // We do not support 565 in HARDWARE, so no RAM savings
+                    // are possible.
+                    assertEquals(normalByteCount, byteCount);
+                } else { // R.raw.f16
+                    // This image defaults to F16. MEMORY_POLICY_LOW_RAM
+                    // forces "test" to decode to 8888.
                     assertTrue(byteCount < normalByteCount);
                 }
             }
@@ -2109,7 +2092,7 @@
             ImageDecoder.Source src = ImageDecoder.createSource(assets, record.name);
             for (ColorSpace cs : new ColorSpace[] {
                     sSRGB,
-                    ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB),
+                    ColorSpace.get(ColorSpace.Named.LINEAR_SRGB),
                     ColorSpace.get(ColorSpace.Named.DISPLAY_P3),
                     ColorSpace.get(ColorSpace.Named.ADOBE_RGB),
                     ColorSpace.get(ColorSpace.Named.BT709),
@@ -2120,9 +2103,9 @@
                     ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB),
                     ColorSpace.get(ColorSpace.Named.ACES),
                     ColorSpace.get(ColorSpace.Named.ACESCG),
-                    // FIXME: This returns LINEAR_EXTENDED_SRGB.
+                    // FIXME: This returns LINEAR_SRGB.
                     // See b/117601185 and b/77276533
-                    //ColorSpace.get(ColorSpace.Named.LINEAR_SRGB),
+                    //ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB),
             }) {
                 try {
                     Bitmap bm = ImageDecoder.decodeBitmap(src, (decoder, info, s) -> {
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 9d7d510..0d5b5dd 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -31,7 +31,9 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.BlendMode;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.ColorSpace;
 import android.graphics.MaskFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -55,11 +57,15 @@
 import android.text.SpannedString;
 
 import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.ColorUtils;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.Locale;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -83,6 +89,42 @@
     }
 
     @Test
+    public void testDefaultColor() {
+        Supplier<Paint> set = () -> {
+            Paint result = new Paint();
+            result.setColor(Color.BLUE);
+            assertEquals(Color.BLUE, result.getColor());
+            result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.RED);
+            assertEquals(Color.RED, result.getShadowLayerColor());
+
+            Paint def = new Paint();
+            result.set(def);
+            return result;
+        };
+        Supplier<Paint> reset = () -> {
+            Paint result = new Paint();
+            result.setColor(Color.GREEN);
+            assertEquals(Color.GREEN, result.getColor());
+            result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.WHITE);
+            assertEquals(Color.WHITE, result.getShadowLayerColor());
+
+            result.reset();
+            return result;
+        };
+        for (Paint p : new Paint[]{ new Paint(),
+                                    new Paint(1),
+                                    new Paint(new Paint()),
+                                    set.get(),
+                                    reset.get()}) {
+            assertEquals(Color.BLACK, p.getColor());
+            assertEquals(Color.TRANSPARENT, p.getShadowLayerColor());
+
+            assertEquals(Color.BLACK, Color.toArgb(p.getColorLong()));
+            assertEquals(Color.TRANSPARENT, Color.toArgb(p.getShadowLayerColorLong()));
+        }
+    }
+
+    @Test
     public void testBreakText() {
         String text = "HIJKLMN";
         char[] textChars = text.toCharArray();
@@ -731,6 +773,46 @@
     }
 
     @Test
+    public void testSetAlpha() {
+        for (ColorSpace.Named e : new ColorSpace.Named[] {
+                ColorSpace.Named.SRGB,
+                ColorSpace.Named.LINEAR_EXTENDED_SRGB,
+                ColorSpace.Named.DISPLAY_P3}) {
+            ColorSpace cs = ColorSpace.get(e);
+
+            // Arbitrary colors
+            final float red = .2f;
+            final float green = .7f;
+            final float blue = .9f;
+            final long desiredColor = Color.pack(red, green, blue, 1.0f, cs);
+
+            Paint p = new Paint();
+            p.setColor(desiredColor);
+            final long origColor = p.getColorLong();
+            assertEquals(desiredColor, origColor);
+
+            final float origRed = Color.red(origColor);
+            final float origGreen = Color.green(origColor);
+            final float origBlue = Color.blue(origColor);
+
+            // There is a slight difference in the packed color.
+            assertEquals(red, Color.red(origColor), 0.002f);
+            assertEquals(green, Color.green(origColor), 0.002f);
+            assertEquals(blue, Color.blue(origColor), 0.002f);
+
+            for (int alpha = 0; alpha <= 255; ++alpha) {
+                p.setAlpha(alpha);
+                assertEquals(alpha, p.getAlpha());
+
+                final long color = p.getColorLong();
+                assertEquals(origRed, Color.red(color), 0.0f);
+                assertEquals(origGreen, Color.green(color), 0.0f);
+                assertEquals(origBlue, Color.blue(color), 0.0f);
+            }
+        }
+    }
+
+    @Test
     public void testSetFilterBitmap() {
         Paint p = new Paint();
 
@@ -2066,4 +2148,99 @@
             default: throw new IllegalArgumentException("Unknown PorterDuffmode: " + mode);
         }
     }
+
+    private void testColorLongs(String methodName, BiConsumer<Paint, Long> setColor,
+                                Function<Paint, Integer> getColor,
+                                Function<Paint, Long> getColorLong) {
+        // Pack SRGB colors into ColorLongs
+        for (int color : new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.BLACK,
+                Color.WHITE, Color.TRANSPARENT }) {
+            final Paint p = new Paint();
+            final long longColor = Color.pack(color);
+            setColor.accept(p, longColor);
+
+            assertEquals(color, getColor.apply(p).intValue());
+            assertEquals(longColor, getColorLong.apply(p).longValue());
+        }
+
+        // Arbitrary colors in various ColorSpaces
+        for (int srgbColor : new int[]{ Color.argb(1.0f, .5f, .5f, .5f),
+                                        Color.argb(1.0f, .3f, .6f, .9f),
+                                        Color.argb(0.5f, .2f, .8f, .7f) }) {
+            for (ColorSpace.Named e : ColorSpace.Named.values()) {
+                ColorSpace cs = ColorSpace.get(e);
+                if (cs.getModel() != ColorSpace.Model.RGB) {
+                    continue;
+                }
+                if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
+                    continue;
+                }
+
+                final long longColor = Color.convert(srgbColor, cs);
+                Paint p = new Paint();
+                setColor.accept(p, longColor);
+                assertEquals(longColor, getColorLong.apply(p).longValue());
+
+                // These tolerances were chosen by trial and error. It is expected that
+                // some conversions do not round-trip perfectly.
+                int tolerance = 0;
+                if (cs.equals(ColorSpace.get(ColorSpace.Named.SMPTE_C))) {
+                    tolerance = 2;
+                }
+                int color = getColor.apply(p);
+                ColorUtils.verifyColor("Paint#" + methodName + " mismatch for " + cs, srgbColor,
+                        color, tolerance);
+            }
+        }
+    }
+
+    @Test
+    public void testSetColorLong() {
+        testColorLongs("setColor", (p, c) -> p.setColor(c), (p) -> p.getColor(),
+                (p) -> p.getColorLong());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetColorXYZ() {
+        Paint p = new Paint();
+        p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetColorLAB() {
+        Paint p = new Paint();
+        p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetColorUnknown() {
+        Paint p = new Paint();
+        p.setColor(-1L);
+    }
+
+    @Test
+    public void testSetShadowLayerLong() {
+        testColorLongs("setShadowLayer", (p, c) -> p.setShadowLayer(10.0f, 1.0f, 1.0f, c),
+                (p) -> p.getShadowLayerColor(), (p) -> p.getShadowLayerColorLong());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetShadowLayerXYZ() {
+        Paint p = new Paint();
+        p.setShadowLayer(10.0f, 1.0f, 1.0f,
+                Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetShadowLayerLAB() {
+        Paint p = new Paint();
+        p.setShadowLayer(10.0f, 1.0f, 1.0f,
+                Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetShadowLayerUnknown() {
+        Paint p = new Paint();
+        p.setShadowLayer(10.0f, 1.0f, 1.0f, -1L);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java b/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
index 6c4b312..8478834 100644
--- a/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
+++ b/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
@@ -17,10 +17,14 @@
 package android.graphics.text.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
 import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
@@ -28,6 +32,9 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.PrecomputedText;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -309,4 +316,109 @@
         new MeasuredText.Builder(text.toCharArray())
                 .appendReplacementRun(sPaint, text.length() - 1, 1.0f).build();
     }
+
+    public Bitmap makeBitmapFromSsb(String text, TextPaint paint, boolean isRtl) {
+        // drawTetRun is not aware of multiple style text.
+        final SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+        final Bitmap ssbBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Canvas ssbCanvas = new Canvas(ssbBitmap);
+        ssbCanvas.save();
+        ssbCanvas.translate(0, 0);
+        ssbCanvas.drawTextRun(ssb, 0, ssb.length(), 0, ssb.length(),
+                0.0f /* x */, 240.0f /* y */, isRtl, paint);
+        ssbCanvas.restore();
+        return ssbBitmap;
+    }
+
+    public Bitmap makeBitmapFromMtWithSamePaint(String text, TextPaint paint, boolean isRtl) {
+        // MeasuredText uses measured result if the given paint is equal to the applied one.
+        final MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
+                .appendStyleRun(paint, text.length(), isRtl)
+                .build();
+        final Bitmap mtBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Canvas mtCanvas = new Canvas(mtBitmap);
+        mtCanvas.save();
+        mtCanvas.translate(0, 0);
+        mtCanvas.drawTextRun(mt, 0, text.length(), 0, text.length(),
+                0.0f /* x */, 240.0f /* y */, isRtl, paint);
+        mtCanvas.restore();
+        return mtBitmap;
+    }
+
+    public Bitmap makeBitmapFromMtWithDifferentPaint(String text, TextPaint paint, boolean isRtl) {
+        // If different paint is provided when drawing, MeasuredText discards the measured result
+        // and recompute immediately. Thus the final output must be the same with given one.
+        final MeasuredText mt2 = new MeasuredText.Builder(text.toCharArray())
+                .appendStyleRun(new Paint(), text.length(), isRtl)
+                .build();
+        final Bitmap mt2Bitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Canvas mt2Canvas = new Canvas(mt2Bitmap);
+        mt2Canvas.save();
+        mt2Canvas.translate(0, 0);
+        mt2Canvas.drawTextRun(mt2, 0, text.length(), 0, text.length(),
+                0.0f /* x */, 240.0f /* y */, isRtl, paint);
+        mt2Canvas.restore();
+        return mt2Bitmap;
+    }
+
+    public Bitmap makeBitmapFromPct(String text, TextPaint paint, boolean isRtl) {
+        final PrecomputedText pct = PrecomputedText.create(
+                text, new PrecomputedText.Params.Builder(paint).build());
+        final Bitmap pctBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Canvas pctCanvas = new Canvas(pctBitmap);
+        pctCanvas.save();
+        pctCanvas.translate(0, 0);
+        pctCanvas.drawTextRun(pct, 0, text.length(), 0, text.length(),
+                0.0f /* x */, 240.0f /* y */, isRtl, paint);
+        pctCanvas.restore();
+        return pctBitmap;
+    }
+
+    @Test
+    public void testCanvasDrawTextRun_sameOutputTestForLatinText() {
+        final TextPaint paint = new TextPaint();
+        paint.setTextSize(30.0f);
+
+        final String text = "Hello, World";
+
+        final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, false);
+        assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, false)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, false)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, false)));
+    }
+
+    @Test
+    public void testCanvasDrawTextRun_sameOutputTestForCJKText() {
+        final TextPaint paint = new TextPaint();
+        paint.setTextSize(30.0f);
+
+        final String text = "\u3042\u3044\u3046\u3048\u304A";
+
+        final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, false);
+        assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, false)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, false)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, false)));
+    }
+
+    @Test
+    public void testCanvasDrawTextRun_sameOutputTestForRTLText() {
+        final TextPaint paint = new TextPaint();
+        paint.setTextSize(30.0f);
+
+        final String text = "\u05D0\u05D1\u05D2\u05D3\u05D4";
+
+        final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+        final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, true);
+        assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, true)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, true)));
+        assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, true)));
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
index 6d85626..44f9b20 100644
--- a/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
@@ -49,7 +49,7 @@
         } else {
             // No biometrics are enrolled. CTSVerifier should test the other error cases.
             assertTrue(mBiometricManager.canAuthenticate()
-                    == BiometricManager.BIOMETRIC_ERROR_NO_BIOMETRICS);
+                    == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED);
         }
     }
 }
diff --git a/tests/tests/jni/AndroidManifest.xml b/tests/tests/jni/AndroidManifest.xml
index 2724573..18ef4c6 100644
--- a/tests/tests/jni/AndroidManifest.xml
+++ b/tests/tests/jni/AndroidManifest.xml
@@ -18,7 +18,7 @@
     package="android.jni.cts">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
+    <application android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java b/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
index 994681f..5874d29 100644
--- a/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
+++ b/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
@@ -33,6 +33,7 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -43,6 +44,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.zip.ZipFile;
 
 @RunWith(Parameterized.class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -134,13 +136,29 @@
         return params;
     }
 
+    private static InputStream getAgentInputStream(ClassLoader cl, String lib) throws Exception {
+        String clfile = ((BaseDexClassLoader) cl).findLibrary(lib);
+        try {
+            return new FileInputStream(clfile);
+        } catch (FileNotFoundException e) {
+            if (clfile.contains(".apk!/")) {
+                // Looks like it might be a zipaligned library. Get it from the apk directly.
+                // Skip the !/
+                String libPath = clfile.substring(clfile.lastIndexOf('!') + 2);
+                String apkPath = clfile.substring(0, clfile.lastIndexOf('!'));
+                ZipFile zip = new ZipFile(apkPath);
+                return zip.getInputStream(zip.getEntry(libPath));
+            } else {
+                throw e;
+            }
+        }
+    }
     private static File copyAgentToFile(String lib) throws Exception {
         ClassLoader cl = AttachingTest.class.getClassLoader();
         assertTrue(cl instanceof BaseDexClassLoader);
 
         File copiedAgent = File.createTempFile("agent", ".so");
-        try (InputStream is = new FileInputStream(
-                ((BaseDexClassLoader) cl).findLibrary(lib))) {
+        try (InputStream is = getAgentInputStream(cl, lib)) {
             try (OutputStream os = new FileOutputStream(copiedAgent)) {
                 byte[] buffer = new byte[64 * 1024];
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 9a83b95..b777a7a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -297,6 +297,9 @@
 
     // TODO: This test will fail until b/117509689 is resolved.
     public void testDESKeySupportedSizes() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         KeyGenerator keyGenerator = getKeyGenerator("DESede");
         KeyGenParameterSpec.Builder goodSpec = getWorkingSpec();
         CountingSecureRandom rng = new CountingSecureRandom();
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index b4b17f1..31b644a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -1114,7 +1114,7 @@
         generator.initialize(new KeyGenParameterSpec.Builder(
                 TEST_ALIAS_1,
                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
-                .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384)
+                .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA256)
                 .setIsStrongBoxBacked(useStrongbox)
                 .build());
         KeyPair keyPair = generator.generateKeyPair();
diff --git a/tests/tests/libcoreapievolution/AndroidTest.xml b/tests/tests/libcoreapievolution/AndroidTest.xml
index f777701..0dd61fa 100644
--- a/tests/tests/libcoreapievolution/AndroidTest.xml
+++ b/tests/tests/libcoreapievolution/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Legacy Libcore test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsLibcoreApiEvolutionTestCases.apk" />
diff --git a/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java b/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
index a7ba9ad..8fea09b 100644
--- a/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
+++ b/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
@@ -23,8 +23,17 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
 import java.text.ParseException;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -40,27 +49,84 @@
 public class ApiEvolutionTest {
 
     /**
-     * Tests for synthetic methods generated by
-     * {@link dalvik.annotation.codegen.CovariantReturnType}.
+     * Tests for the presence of a synthetic overload for a subclass method override
+     * that has a more specific (sub-) return type, but doesn't carry any annotation.
      */
     @Test
-    public void testCovariantReturnTypeMethods() throws Exception {
-        // Example of the "normal" way round for synthetic methods generated by the toolchain when
-        // a subclass has a more specific return type.
+    public void testCovariantReturnTypeMethods_specializingSubclass() throws Exception {
         // Exceptions are not required to be identical in this case because the synthetic method
         // mirrors the superclass version.
         assertSyntheticMethodOverloadExists(
                 Sub.class, "myMethod", new Class[] { Integer.class },
                 String.class, Object.class,
                 false /* requireIdenticalExceptions */);
+    }
 
-        // Cases of synthetic platform methods that have been introduced by the platform build tools
-        // in response to the presence of a @CovarientReturnType annotation.
-        // More should be added for every use of the annotation.
+    /**
+     * Tests for the presence of a synthetic overload for {@link ConcurrentHashMap#keySet}
+     * that must be introduced by the platform build tools in response to the presence of a
+     * {@link dalvik.annotation.codegen.CovariantReturnType} annotation. http://b/28099367
+     */
+    @Test
+    public void testCovariantReturnTypeMethods_annotation_concurrentHashMap() throws Exception {
         assertSyntheticMethodOverloadExists(ConcurrentHashMap.class, "keySet", null, Set.class,
                 ConcurrentHashMap.KeySetView.class, true);
     }
 
+    @Test public void testCovariantReturnTypeMethods_annotation_byteBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(ByteBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_charBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(CharBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_doubleBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(DoubleBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_floatBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(FloatBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_intBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(IntBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_longBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(LongBuffer.class);
+    }
+
+    @Test public void testCovariantReturnTypeMethods_annotation_shortBuffer() throws Exception {
+        assertSyntheticBufferMethodOverloadsExists(ShortBuffer.class);
+    }
+
+    /**
+     * Asserts the presence of synthetic methods overloads for methods that return {@code this} on
+     * {@link Buffer} subclasses, and which are annotated with {@code @CovariantReturnType}.
+     * In OpenJDK 9 the return types were changed from {@link Buffer} to be the subclass's type
+     * instead. http://b/71597787
+     */
+    private static void assertSyntheticBufferMethodOverloadsExists(Class<? extends Buffer> c)
+            throws Exception {
+        assertSyntheticBufferMethodOverloadExists(c, "position", new Class[] { Integer.TYPE });
+        assertSyntheticBufferMethodOverloadExists(c, "limit", new Class[] { Integer.TYPE });
+        assertSyntheticBufferMethodOverloadExists(c, "mark", null);
+        assertSyntheticBufferMethodOverloadExists(c, "reset", null);
+        assertSyntheticBufferMethodOverloadExists(c, "clear", null);
+        assertSyntheticBufferMethodOverloadExists(c, "flip", null);
+        assertSyntheticBufferMethodOverloadExists(c, "rewind", null);
+    }
+
+    private static void assertSyntheticBufferMethodOverloadExists(
+            Class<? extends Buffer> bufferClass, String methodName, Class[] parameterTypes)
+            throws Exception {
+        assertSyntheticMethodOverloadExists(bufferClass, methodName, parameterTypes,
+                Buffer.class /* originalReturnType */,
+                bufferClass /* syntheticReturnType */,
+                true  /* requireIdenticalExceptions */);
+    }
+
     private static void assertSyntheticMethodOverloadExists(
             Class<?> clazz, String methodName, Class[] parameterTypes,
             Class<?> originalReturnType, Class<?> syntheticReturnType,
diff --git a/tests/tests/libcorefileio/AndroidTest.xml b/tests/tests/libcorefileio/AndroidTest.xml
index 074a833..65926f8 100644
--- a/tests/tests/libcorefileio/AndroidTest.xml
+++ b/tests/tests/libcorefileio/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Legacy Libcore test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsLibcoreFileIOTestCases.apk" />
diff --git a/tests/tests/libcorelegacy22/AndroidTest.xml b/tests/tests/libcorelegacy22/AndroidTest.xml
index d5409d7..d1706d9 100644
--- a/tests/tests/libcorelegacy22/AndroidTest.xml
+++ b/tests/tests/libcorelegacy22/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Legacy Libcore test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsLibcoreLegacy22TestCases.apk" />
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index daa8d33..5d17e80 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -255,64 +255,6 @@
     }
 
     /**
-     * Tests that location mode is consistent with which providers are enabled. Sadly we can only
-     * passively test whatever mode happens to be selected--actually changing the mode would require
-     * the test to be system-signed, and CTS tests aren't. Also mode changes that enable NLP require
-     * user consent. Thus we will have a manual CTS verifier test that is similar to this test but
-     * tests every location mode. This test is just a "backup" for that since verifier tests are
-     * less reliable.
-     */
-    public void testModeAndProviderApisConsistent() {
-        ContentResolver cr = mContext.getContentResolver();
-
-        // Find out what the settings say about which providers are enabled
-        int mode = Settings.Secure.getInt(
-                cr, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
-        boolean gps = Settings.Secure.isLocationProviderEnabled(cr, LocationManager.GPS_PROVIDER);
-        boolean nlp = Settings.Secure.isLocationProviderEnabled(
-                cr, LocationManager.NETWORK_PROVIDER);
-
-        // Find out location manager's opinion on the matter, making sure we dont' get spurious
-        // results from test versions of the two providers.
-        forceRemoveTestProvider(LocationManager.GPS_PROVIDER);
-        forceRemoveTestProvider(LocationManager.NETWORK_PROVIDER);
-        boolean lmGps = mManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
-        boolean lmNlp = mManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
-
-        // Location Manager will report provider as off if it doesn't know about it
-        boolean expectedGps = gps && deviceHasProvider(LocationManager.GPS_PROVIDER);
-        boolean expectedNlp = nlp && deviceHasProvider(LocationManager.NETWORK_PROVIDER);
-
-        // Assert LocationManager returned the values from Settings.Secure (assuming the device has
-        // the appropriate hardware).
-        assertEquals("Inconsistent GPS values", expectedGps, lmGps);
-        assertEquals("Inconsistent NLP values", expectedNlp, lmNlp);
-
-        switch (mode) {
-            case Settings.Secure.LOCATION_MODE_OFF:
-                expectedGps = false;
-                expectedNlp = false;
-                break;
-            case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
-                expectedGps = true;
-                expectedNlp = false;
-                break;
-            case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
-                expectedGps = false;
-                expectedNlp = true;
-                break;
-            case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
-                expectedGps = true;
-                expectedNlp = true;
-                break;
-        }
-
-        // Assert that isLocationProviderEnabled() values are consistent with the location mode
-        assertEquals("Bad GPS for mode " + mode, expectedGps, gps);
-        assertEquals("Bad NLP for mode " + mode, expectedNlp, nlp);
-    }
-
-    /**
      * Returns true if the {@link LocationManager} reports that the device includes this flavor
      * of location provider.
      */
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index e4fa41f..c9ffe61 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -72,6 +72,7 @@
     // android/hardware/libhardware/include/hardware/gps.h
     public static final Set<Integer> GNSS_NAVIGATION_MESSAGE_TYPE =
         new HashSet<Integer>(Arrays.asList(
+            GnssNavigationMessage.TYPE_UNKNOWN,
             GnssNavigationMessage.TYPE_GPS_L1CA,
             GnssNavigationMessage.TYPE_GPS_L2CNAV,
             GnssNavigationMessage.TYPE_GPS_L5CNAV,
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 11d687d..dc77eed 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -85,7 +85,8 @@
 LOCAL_JAVA_LIBRARIES += \
     org.apache.http.legacy \
     android.test.base.stubs \
-    android.test.runner.stubs
+    android.test.runner.stubs \
+    updatable-media # TODO(b/112766913): replace with stub to prevent private API use.
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index c4bf99f..1b816d3 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -31,6 +31,8 @@
     <uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
     <uses-permission android:name="android.permission.SET_MEDIA_KEY_LISTENER" />
 
+    <permission android:name="android.media.cts" android:protectionLevel="normal" />
+
     <application android:networkSecurityConfig="@xml/network_security_config">
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
@@ -100,6 +102,12 @@
                 <action android:name="android.media.browse.MediaBrowserService" />
             </intent-filter>
         </service>
+        <service android:name="android.media.cts.StubMediaSession2Service"
+            android:permission="android.media.cts">
+            <intent-filter>
+                <action android:name="android.media.MediaSession2Service" />
+            </intent-filter>
+        </service>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index da99a12..3391aa3 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -47,6 +47,7 @@
 import java.util.Vector;
 import java.util.zip.CRC32;
 
+@MediaHeavyPresubmitTest
 @AppModeFull
 public class AdaptivePlaybackTest extends MediaPlayerTestBase {
     private static final String TAG = "AdaptivePlaybackTest";
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index 2a056e4..0f404d1 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -49,6 +49,7 @@
 
 @TargetApi(24)
 @RunWith(Parameterized.class)
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "There should be no instant apps specific behavior related to accuracy")
 public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
 
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 62d2fbd..8cb2a27 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -59,6 +59,7 @@
 
 import static android.media.MediaCodecInfo.CodecProfileLevel.*;
 
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "There should be no instant apps specific behavior related to decoders")
 public class DecoderTest extends MediaPlayerTestBase {
     private static final String TAG = "DecoderTest";
@@ -2429,7 +2430,19 @@
         // start decode loop
         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
 
-        final long kTimeOutUs = 5000; // 5ms timeout
+        MediaFormat outFormat = codec.getOutputFormat();
+        long kTimeOutUs = 5000; // 5ms timeout
+        String outMime = format.getString(MediaFormat.KEY_MIME);
+        if ((surface == null) && (outMime != null) && outMime.startsWith("video/")) {
+            int outWidth = outFormat.getInteger(MediaFormat.KEY_WIDTH);
+            int outHeight = outFormat.getInteger(MediaFormat.KEY_HEIGHT);
+            // in the 4K decoding case in byte buffer mode, set kTimeOutUs to 10ms as decode may
+            // involve a memcpy
+            if (outWidth * outHeight >= 8000000) {
+                kTimeOutUs = 10000;
+            }
+        }
+
         boolean sawInputEOS = false;
         boolean sawOutputEOS = false;
         int deadDecoderCounter = 0;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index cf2e8f6..7f08662 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -24,6 +24,8 @@
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
 import android.media.MediaMuxer;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -41,6 +43,8 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+@SmallTest
+@RequiresDevice
 public class EncoderTest extends AndroidTestCase {
     private static final String TAG = "EncoderTest";
     private static final boolean VERBOSE = false;
@@ -151,18 +155,28 @@
             MediaUtils.skipTest("no encoders found for " + Arrays.toString(formats));
             return;
         }
-        ExecutorService pool = Executors.newFixedThreadPool(3);
+
+        int ThreadCount = 3;
+        int testsStarted = 0;
+        int allowPerTest = 30;
+
+        ExecutorService pool = Executors.newFixedThreadPool(ThreadCount);
 
         for (String componentName : componentNames) {
             for (MediaFormat format : formats) {
                 assertEquals(mime, format.getString(MediaFormat.KEY_MIME));
                 pool.execute(new EncoderRun(componentName, format));
+                testsStarted++;
             }
         }
         try {
             pool.shutdown();
+            int waitingSeconds = ((testsStarted + ThreadCount - 1) / ThreadCount) * allowPerTest;
+            waitingSeconds += 300;
+            Log.i(TAG, "waiting up to " + waitingSeconds + " seconds for "
+                            + testsStarted + " sub-tests to finish");
             assertTrue("timed out waiting for encoder threads",
-                    pool.awaitTermination(10, TimeUnit.MINUTES));
+                    pool.awaitTermination(waitingSeconds, TimeUnit.SECONDS));
         } catch (InterruptedException e) {
             fail("interrupted while waiting for encoder threads");
         }
diff --git a/tests/tests/media/src/android/media/cts/HandlerExecutor.java b/tests/tests/media/src/android/media/cts/HandlerExecutor.java
new file mode 100644
index 0000000..afeef51e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/HandlerExecutor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+public class HandlerExecutor extends Handler implements Executor {
+    public HandlerExecutor(@NonNull Looper looper) {
+        super(looper);
+    }
+
+    @Override
+    public void execute(Runnable command) {
+        if (!post(command)) {
+            throw new RejectedExecutionException(this + " is shutting down");
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index 540e3ff..1dd77d9 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -38,6 +38,8 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
 import android.test.AndroidTestCase;
 import android.util.Log;
 import android.view.Surface;
@@ -66,6 +68,8 @@
  * test. For decoder test, hw and sw decoders are tested,
  * </p>
  */
+@SmallTest
+@RequiresDevice
 public class ImageReaderDecoderTest extends AndroidTestCase {
     private static final String TAG = "ImageReaderDecoderTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 4ac23a9..ec0c8f0 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -29,6 +29,7 @@
 import android.media.MediaCodecList;
 import android.media.MediaCrypto;
 import android.media.MediaDrm;
+import android.media.MediaDrm.MediaDrmStateException;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.media.MediaCodecInfo.CodecCapabilities;
@@ -49,6 +50,7 @@
 import com.android.compatibility.common.util.MediaUtils;
 
 import java.io.BufferedInputStream;
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
@@ -1945,11 +1947,70 @@
         return actualEncoding;
     }
 
-    abstract class ByteBufferStream {
+    /*
+     * Simulate ERROR_LOST_STATE error during decryption, expected
+     * result is MediaCodec.CryptoException with errorCode == ERROR_LOST_STATE
+     */
+    public void testCryptoErrorLostSessionState() throws Exception {
+        if (!supportsCodec(MIME_TYPE, true)) {
+            Log.i(TAG, "No encoder found for mimeType= " + MIME_TYPE);
+            return;
+        }
+
+        MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+        drm.setPropertyString("drmErrorTest", "lostState");
+
+        byte[] sessionId = drm.openSession();
+        MediaCrypto crypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, new byte[0]);
+        MediaCodec codec = MediaCodec.createDecoderByType(MIME_TYPE);
+
+        try {
+            crypto.setMediaDrmSession(sessionId);
+
+            MediaCodec.CryptoInfo cryptoInfo = new MediaCodec.CryptoInfo();
+            MediaFormat format = createMediaFormat();
+
+            codec.configure(format, null, crypto, 0);
+            codec.start();
+            int index = codec.dequeueInputBuffer(-1);
+            assertTrue(index >= 0);
+            ByteBuffer buffer = codec.getInputBuffer(index);
+            cryptoInfo.set(
+                    1,
+                    new int[] { 0 },
+                    new int[] { buffer.capacity() },
+                            new byte[16],
+                    new byte[16],
+                    MediaCodec.CRYPTO_MODE_AES_CTR);
+            try {
+                codec.queueSecureInputBuffer(index, 0, cryptoInfo, 0, 0);
+                fail("queueSecureInputBuffer should fail when trying to decrypt " +
+                        "after session lost state error.");
+            } catch (MediaCodec.CryptoException e) {
+                if (e.getErrorCode() != MediaCodec.CryptoException.ERROR_LOST_STATE) {
+                    fail("expected MediaCodec.CryptoException.ERROR_LOST_STATE: " +
+                            e.getErrorCode() + ": " + e.getMessage());
+                }
+                // received expected lost state exception
+            }
+            buffer = codec.getInputBuffer(index);
+            codec.stop();
+        } finally {
+            codec.release();
+            crypto.release();
+            try {
+                drm.closeSession(sessionId);
+            } catch (MediaDrmStateException e) {
+                // expected since session lost state
+            }
+        }
+    }
+
+    /* package */ static abstract class ByteBufferStream {
         public abstract ByteBuffer read() throws IOException;
     }
 
-    class MediaCodecStream extends ByteBufferStream {
+    /* package */ static class MediaCodecStream extends ByteBufferStream implements Closeable {
         private ByteBufferStream mBufferInputStream;
         private InputStream mInputStream;
         private MediaCodec mCodec;
@@ -2012,6 +2073,7 @@
             mBufferInputStream = input;
         }
 
+        @Override
         public ByteBuffer read() throws IOException {
 
             if (mSawOutputEOS) {
@@ -2102,6 +2164,7 @@
             return ByteBuffer.allocate(0);
         }
 
+        @Override
         public void close() throws IOException {
             try {
                 if (mInputStream != null) {
@@ -2128,7 +2191,7 @@
         }
     };
 
-    class ByteBufferInputStream extends InputStream {
+    /* package */ static class ByteBufferInputStream extends InputStream {
         ByteBufferStream mInput;
         ByteBuffer mBuffer;
 
@@ -2152,7 +2215,7 @@
         }
     };
 
-    class PcmAudioBufferStream extends ByteBufferStream {
+    /* package */ static class PcmAudioBufferStream extends ByteBufferStream {
 
         public int mCount;         // either 0 or 1 if the buffer has been delivered
         public ByteBuffer mBuffer; // the audio buffer (furnished duplicated, read only).
@@ -2200,7 +2263,7 @@
         }
     }
 
-    private int compareStreams(InputStream test, InputStream reference) {
+    /* package */ static int compareStreams(InputStream test, InputStream reference) {
         Log.i(TAG, "compareStreams");
         BufferedInputStream buffered_test = new BufferedInputStream(test);
         BufferedInputStream buffered_reference = new BufferedInputStream(reference);
@@ -2229,52 +2292,51 @@
 
     @SmallTest
     public void testFlacIdentity() throws Exception {
-        final int FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
-        final int SAMPLES = FRAMES * AUDIO_CHANNEL_COUNT;
+        final int PCM_FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
+        final int SAMPLES = PCM_FRAMES * AUDIO_CHANNEL_COUNT;
+        final int[] SAMPLE_RATES = {AUDIO_SAMPLE_RATE, 192000}; // ensure 192kHz supported.
 
-        final MediaFormat format = new MediaFormat();
-        format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
-        format.setInteger(MediaFormat.KEY_SAMPLE_RATE, AUDIO_SAMPLE_RATE);
-        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, AUDIO_CHANNEL_COUNT);
+        for (int sampleRate : SAMPLE_RATES) {
+            final MediaFormat format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
+            format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
+            format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, AUDIO_CHANNEL_COUNT);
 
-        // this key is only needed for encode, ignored for decode
-        format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
+            Log.d(TAG, "Trying sample rate: " + sampleRate
+                    + " channel count: " + AUDIO_CHANNEL_COUNT);
+            // this key is only needed for encode, ignored for decode
+            format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
 
-        for (int i = 0; i < 2; ++i) {
-            final boolean useFloat = (i == 1);
-            final PcmAudioBufferStream audioStream = new PcmAudioBufferStream(
-                    SAMPLES, AUDIO_SAMPLE_RATE, 1000 /* frequency */, 100 /* sweep */, useFloat);
+            for (int i = 0; i < 2; ++i) {
+                final boolean useFloat = (i == 1);
+                final PcmAudioBufferStream audioStream = new PcmAudioBufferStream(
+                    SAMPLES, sampleRate, 1000 /* frequency */, 100 /* sweep */, useFloat);
 
-            if (useFloat) {
-                format.setInteger(
-                    MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT);
-            }
+                if (useFloat) {
+                    format.setInteger(
+                        MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT);
+                }
 
-            final MediaCodecStream rawToFlac = new MediaCodecStream(
+                final MediaCodecStream rawToFlac = new MediaCodecStream(
                     new ByteBufferInputStream(audioStream), format, true /* encode */);
-            final MediaCodecStream flacToRaw = new MediaCodecStream(
+                final MediaCodecStream flacToRaw = new MediaCodecStream(
                     rawToFlac, format, false /* encode */);
 
-            if (useFloat) {
-                if (!rawToFlac.mIsFloat) {
-                    Log.d(TAG, "No floating point FLAC encoder");
+                if (useFloat) { // ensure float precision supported at the sample rate.
+                    assertTrue("No float FLAC encoder at " + sampleRate,
+                            rawToFlac.mIsFloat);
+                    assertTrue("No float FLAC decoder at " + sampleRate,
+                            flacToRaw.mIsFloat);
                 }
-                if (!flacToRaw.mIsFloat) {
-                    Log.d(TAG, "No floating point FLAC decoder");
-                }
-                if (!rawToFlac.mIsFloat || !flacToRaw.mIsFloat) {
-                    break;
-                }
-                // TODO: should these be errors?
-            }
 
-            // Note: the existence of signed zero (as well as NAN) may make byte
-            // comparisons invalid for floating point output. In our case, since the
-            // floats come through integer to float conversion, it does not matter.
-            assertEquals("not identical after compression",
-                audioStream.sizeInBytes(),
-                compareStreams(new ByteBufferInputStream(flacToRaw),
+                // Note: the existence of signed zero (as well as NAN) may make byte
+                // comparisons invalid for floating point output. In our case, since the
+                // floats come through integer to float conversion, it does not matter.
+                assertEquals("Audio data not identical after compression",
+                    audioStream.sizeInBytes(),
+                    compareStreams(new ByteBufferInputStream(flacToRaw),
                         new ByteBufferInputStream(new PcmAudioBufferStream(audioStream))));
+            }
         }
     }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaController2Test.java b/tests/tests/media/src/android/media/cts/MediaController2Test.java
new file mode 100644
index 0000000..945c95a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaController2Test.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link android.media.MediaController2}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaController2Test {
+    private static final long WAIT_TIME_MS = 100L;
+
+    static final Object sTestLock = new Object();
+
+    static final int ALLOWED_COMMAND_CODE = 100;
+    static final Session2CommandGroup SESSION_ALLOWED_COMMANDS = new Session2CommandGroup.Builder()
+            .addCommand(ALLOWED_COMMAND_CODE).build();
+    static final int SESSION_RESULT_CODE = 100;
+    static final String SESSION_RESULT_KEY = "test_result_key";
+    static final String SESSION_RESULT_VALUE = "test_result_value";
+    static final Session2Command.Result SESSION_COMMAND_RESULT;
+
+    static {
+        Bundle resultData = new Bundle();
+        resultData.putString(SESSION_RESULT_KEY, SESSION_RESULT_VALUE);
+        SESSION_COMMAND_RESULT = new Session2Command.Result(SESSION_RESULT_CODE, resultData);
+    }
+
+    static Handler sHandler;
+    static Executor sHandlerExecutor;
+
+    private Context mContext;
+    private MediaSession2 mSession;
+    private Session2Callback mSessionCallback;
+
+    @BeforeClass
+    public static void setUpThread() {
+        synchronized (MediaSession2Test.class) {
+            if (sHandler != null) {
+                return;
+            }
+            HandlerThread handlerThread = new HandlerThread("MediaSessionTestBase");
+            handlerThread.start();
+            sHandler = new Handler(handlerThread.getLooper());
+            sHandlerExecutor = (runnable) -> {
+                Handler handler;
+                synchronized (MediaSession2Test.class) {
+                    handler = sHandler;
+                }
+                if (handler != null) {
+                    handler.post(() -> {
+                        synchronized (sTestLock) {
+                            runnable.run();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    @AfterClass
+    public static void cleanUpThread() {
+        synchronized (MediaSession2Test.class) {
+            if (sHandler == null) {
+                return;
+            }
+            sHandler.getLooper().quitSafely();
+            sHandler = null;
+            sHandlerExecutor = null;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mSessionCallback = new Session2Callback();
+        mSession = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, mSessionCallback)
+                .build();
+    }
+
+    @After
+    public void cleanUp() {
+        if (mSession != null) {
+            mSession.close();
+            mSession = null;
+        }
+    }
+
+    @Test
+    public void testGetConnectedToken() {
+        Controller2Callback controllerCallback = new Controller2Callback();
+        try (MediaController2 controller = new MediaController2(
+                mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+            assertEquals(controller, controllerCallback.mController);
+            assertEquals(mSession.getSessionToken(), controller.getConnectedSessionToken());
+        } finally {
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+            assertNull(controllerCallback.mController.getConnectedSessionToken());
+        }
+    }
+
+    @Test
+    public void testCallback_onConnected_onDisconnected() {
+        Controller2Callback controllerCallback = new Controller2Callback();
+        try (MediaController2 controller = new MediaController2(
+                mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+            assertEquals(controller, controllerCallback.mController);
+            assertTrue(controllerCallback.mAllowedCommands.hasCommand(ALLOWED_COMMAND_CODE));
+        } finally {
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testCallback_onSessionCommand() {
+        Controller2Callback controllerCallback = new Controller2Callback();
+        try (MediaController2 controller = new MediaController2(
+                mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+            String commandStr = "test_command";
+            String commandExtraKey = "test_extra_key";
+            String commandExtraValue = "test_extra_value";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key";
+            String commandArgValue = "test_arg_value";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            mSession.sendSessionCommand(mSessionCallback.mControllerInfo, command, commandArg);
+
+            assertTrue(controllerCallback.awaitOnSessionCommand(WAIT_TIME_MS));
+            assertEquals(controller, controllerCallback.mController);
+            assertEquals(commandStr, controllerCallback.mCommand.getCustomCommand());
+            assertEquals(commandExtraValue,
+                    controllerCallback.mCommand.getExtras().getString(commandExtraKey));
+            assertEquals(commandArgValue, controllerCallback.mCommandArgs.getString(commandArgKey));
+        } finally {
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testCallback_onCommandResult() {
+        Controller2Callback controllerCallback = new Controller2Callback();
+        try (MediaController2 controller = new MediaController2(
+                mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+            String commandStr = "test_command";
+            String commandExtraKey = "test_extra_key";
+            String commandExtraValue = "test_extra_value";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key";
+            String commandArgValue = "test_arg_value";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            controller.sendSessionCommand(command, commandArg);
+
+            assertTrue(controllerCallback.awaitOnCommandResult(WAIT_TIME_MS));
+            assertEquals(controller, controllerCallback.mController);
+            assertEquals(SESSION_RESULT_CODE, controllerCallback.mCommandResult.getResultCode());
+            assertEquals(SESSION_RESULT_VALUE,
+                    controllerCallback.mCommandResult.getResultData()
+                            .getString(SESSION_RESULT_KEY));
+        } finally {
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testCancelSessionCommand() {
+        Controller2Callback controllerCallback = new Controller2Callback();
+        try (MediaController2 controller = new MediaController2(
+                mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+            String commandStr = "test_command_";
+            String commandExtraKey = "test_extra_key_";
+            String commandExtraValue = "test_extra_value_";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key_";
+            String commandArgValue = "test_arg_value_";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            synchronized (sTestLock) {
+                Object token = controller.sendSessionCommand(command, commandArg);
+                controller.cancelSessionCommand(token);
+            }
+            assertTrue(controllerCallback.awaitOnCommandResult(WAIT_TIME_MS));
+            assertEquals(Session2Command.RESULT_INFO_SKIPPED,
+                    controllerCallback.mCommandResult.getResultCode());
+        } finally {
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    class Session2Callback extends MediaSession2.SessionCallback {
+        MediaSession2.ControllerInfo mControllerInfo;
+
+        @Override
+        public Session2CommandGroup onConnect(MediaSession2 session,
+                MediaSession2.ControllerInfo controller) {
+            mControllerInfo = controller;
+            return SESSION_ALLOWED_COMMANDS;
+        }
+
+        @Override
+        public Session2Command.Result onSessionCommand(MediaSession2 session,
+                MediaSession2.ControllerInfo controller, Session2Command command, Bundle args) {
+            return SESSION_COMMAND_RESULT;
+        }
+    }
+
+    class Controller2Callback extends MediaController2.ControllerCallback {
+        CountDownLatch mOnConnectedLatch = new CountDownLatch(1);
+        CountDownLatch mOnDisconnectedLatch = new CountDownLatch(1);
+        private CountDownLatch mOnSessionCommandLatch = new CountDownLatch(1);
+        private CountDownLatch mOnCommandResultLatch = new CountDownLatch(1);
+
+        MediaController2 mController;
+        Session2Command mCommand;
+        Session2CommandGroup mAllowedCommands;
+        Bundle mCommandArgs;
+        Session2Command.Result mCommandResult;
+
+        public boolean await(long waitMs) {
+            try {
+                return mOnSessionCommandLatch.await(waitMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        @Override
+        public void onConnected(MediaController2 controller, Session2CommandGroup allowedCommands) {
+            mController = controller;
+            mAllowedCommands = allowedCommands;
+            mOnConnectedLatch.countDown();
+        }
+
+        @Override
+        public void onDisconnected(MediaController2 controller) {
+            mController = controller;
+            mOnDisconnectedLatch.countDown();
+        }
+
+        @Override
+        public Session2Command.Result onSessionCommand(MediaController2 controller,
+                Session2Command command, Bundle args) {
+            mController = controller;
+            mCommand = command;
+            mCommandArgs = args;
+            mOnSessionCommandLatch.countDown();
+            return SESSION_COMMAND_RESULT;
+        }
+
+        @Override
+        public void onCommandResult(MediaController2 controller,Object token,
+                Session2Command command, Session2Command.Result result) {
+            mController = controller;
+            mCommand = command;
+            mCommandResult = result;
+            mOnCommandResultLatch.countDown();
+        }
+
+        public boolean awaitOnConnected(long waitTimeMs) {
+            try {
+                return mOnConnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnDisconnected(long waitTimeMs) {
+            try {
+                return mOnDisconnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnSessionCommand(long waitTimeMs) {
+            try {
+                return mOnSessionCommandLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnCommandResult(long waitTimeMs) {
+            try {
+                return mOnCommandResultLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index ec2be4d..16f8863 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -109,6 +109,7 @@
     private MediaDrm mDrm = null;
     private final Object mLock = new Object();
     private SurfaceHolder mSurfaceHolder;
+    private boolean mLostStateReceived;
 
     @Override
     protected void setUp() throws Exception {
@@ -285,6 +286,20 @@
                                 }
                             }
                         });
+                    mDrm.setOnSessionLostStateListener(new MediaDrm.OnSessionLostStateListener() {
+                            @Override
+                            public void onSessionLostState(MediaDrm md, byte[] sid) {
+                                if (md != mDrm) {
+                                    Log.e(TAG, "onSessionLostState callback: drm object mismatch");
+                                } else if (!Arrays.equals(mSessionId, sid)) {
+                                    Log.e(TAG, "onSessionLostState callback: sessionId mismatch: |" +
+                                            Arrays.toString(mSessionId) + "| vs |" + Arrays.toString(sid) + "|");
+                                } else {
+                                    mLostStateReceived = true;
+                                }
+                            }
+                        }, null);
+
                     mLock.notify();
                 }
                 Looper.loop();  // Blocks forever until Looper.quit() is called.
@@ -1163,6 +1178,111 @@
         }
     }
 
+    /**
+     * Test that the framework handles a device returning
+     * ::android::hardware::drm@1.2::Status::ERROR_DRM_RESOURCE_CONTENTION.
+     * Expected behavior: throws MediaDrm.SessionException with
+     * errorCode ERROR_RESOURCE_CONTENTION
+     */
+    public void testResourceContentionError() {
+
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        MediaDrm drm = null;
+        boolean gotException = false;
+
+        try {
+            drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+            drm.setPropertyString("drmErrorTest", "resourceContention");
+            byte[] sessionId = drm.openSession();
+
+            try {
+                byte[] ignoredInitData = new byte[] { 1 };
+                drm.getKeyRequest(sessionId, ignoredInitData, "cenc", MediaDrm.KEY_TYPE_STREAMING, null);
+            } catch (MediaDrm.SessionException e) {
+                if (e.getErrorCode() != MediaDrm.SessionException.ERROR_RESOURCE_CONTENTION) {
+                    throw new Error("Incorrect error code, expected ERROR_RESOURCE_CONTENTION");
+                }
+                gotException = true;
+            }
+        } catch(Exception e) {
+            throw new Error("Unexpected exception ", e);
+        } finally {
+            if (drm != null) {
+                drm.close();
+            }
+        }
+        if (!gotException) {
+            throw new Error("Didn't receive expected MediaDrm.SessionException");
+        }
+    }
+
+    /**
+     * Test that the framework handles a device returning invoking
+     * the ::android::hardware::drm@1.2::sendSessionLostState callback
+     * Expected behavior: OnSessionLostState is called with
+     * the sessionId
+     */
+    public void testSessionLostStateError() {
+
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        boolean gotException = false;
+        mLostStateReceived = false;
+
+        MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC }, "cenc",
+                CLEARKEY_SCHEME_UUID, MediaDrm.KEY_TYPE_STREAMING);
+
+        mDrm.setPropertyString("drmErrorTest", "lostState");
+        mSessionId = openSession(drm);
+
+        // simulates session lost state here, detected by closeSession
+
+        try {
+            try {
+                closeSession(drm, mSessionId);
+            } catch (MediaDrmStateException e) {
+                gotException = true; // expected for lost state
+            }
+            // wait up to 2 seconds for event
+            for (int i = 0; i < 20 && !mLostStateReceived; i++) {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+            }
+            if (!mLostStateReceived) {
+                throw new Error("Callback for OnSessionLostStateListener not received");
+            }
+        } catch(Exception e) {
+            throw new Error("Unexpected exception ", e);
+        } finally {
+            stopDrm(drm);
+        }
+        if (!gotException) {
+            throw new Error("Didn't receive expected MediaDrmStateException");
+        }
+    }
+
+    public void testIsCryptoSchemeSupportedWithSecurityLevel() {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        if (MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID, "cenc",
+                                             MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL)) {
+            throw new Error("Clearkey claims to support SECURITY_LEVEL_HW_SECURE_ALL");
+        }
+        if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID, "cenc",
+                                              MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO)) {
+            throw new Error("Clearkey claims not to support SECURITY_LEVEL_SW_SECURE_CRYPTO");
+        }
+    }
+
     private String getClearkeyVersion(MediaDrm drm) {
         try {
             return drm.getPropertyString("version");
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
index 87ae2c0..2ac83cf 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
@@ -20,11 +20,11 @@
 import static org.hamcrest.Matchers.lessThanOrEqualTo;
 
 import android.media.MediaDrm;
-import android.media.MediaDrm.MediaDrmStateException;
 import android.os.PersistableBundle;
 import android.test.AndroidTestCase;
 import android.util.Log;
 import com.google.common.io.BaseEncoding;
+import java.lang.IllegalArgumentException;
 import java.util.Base64;
 import java.util.HashSet;
 import java.util.StringJoiner;
@@ -144,7 +144,7 @@
 
         try {
           drm.getKeyRequest(sid, null, "", 2, null);
-        } catch (MediaDrmStateException e) {
+        } catch (IllegalArgumentException e) {
           // Exception expected.
         }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 6e5898d..c5cfeef 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -23,20 +23,26 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.icu.util.ULocale;
+import android.media.AudioFormat;
 import android.media.AudioPresentation;
 import android.media.MediaDataSource;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.os.PersistableBundle;
+import android.support.test.filters.SmallTest;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.io.Closeable;
+import java.io.InputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
 import java.io.InputStreamReader;
 import java.io.BufferedReader;
 import java.io.Reader;
@@ -295,4 +301,192 @@
             strTok.nextToken();
         } while (srcAdvance);
     }
+
+    /* package */ static class ByteBufferDataSource extends MediaDataSource {
+        private final long mSize;
+        private TreeMap<Long, ByteBuffer> mMap = new TreeMap<Long, ByteBuffer>();
+
+        public ByteBufferDataSource(MediaCodecTest.ByteBufferStream bufferStream)
+                throws IOException {
+            long size = 0;
+            while (true) {
+                final ByteBuffer buffer = bufferStream.read();
+                if (buffer == null) break;
+                final int limit = buffer.limit();
+                if (limit == 0) continue;
+                size += limit;
+                mMap.put(size - 1, buffer); // key: last byte of validity for the buffer.
+            }
+            mSize = size;
+        }
+
+        @Override
+        public long getSize() {
+            return mSize;
+        }
+
+        @Override
+        public int readAt(long position, byte[] buffer, int offset, int size) {
+            Log.v(TAG, "reading at " + position + " offset " + offset + " size " + size);
+
+            // This chooses all buffers with key >= position (e.g. valid buffers)
+            final SortedMap<Long, ByteBuffer> map = mMap.tailMap(position);
+            int copied = 0;
+            for (Map.Entry<Long, ByteBuffer> e : map.entrySet()) {
+                // Get a read-only version of the byte buffer.
+                final ByteBuffer bb = e.getValue().asReadOnlyBuffer();
+                // Convert read position to an offset within that byte buffer, bboffs.
+                final long bboffs = position - e.getKey() + bb.limit() - 1;
+                if (bboffs >= bb.limit() || bboffs < 0) {
+                    break; // (negative position)?
+                }
+                bb.position((int)bboffs); // cast is safe as bb.limit is int.
+                final int tocopy = Math.min(size, bb.remaining());
+                if (tocopy == 0) {
+                    break; // (size == 0)?
+                }
+                bb.get(buffer, offset, tocopy);
+                copied += tocopy;
+                size -= tocopy;
+                offset += tocopy;
+                position += tocopy;
+                if (size == 0) {
+                    break; // finished copying.
+                }
+            }
+            if (copied == 0) {
+                copied = -1;  // signal end of file
+            }
+            return copied;
+        }
+
+        @Override
+        public void close() {
+            mMap = null;
+        }
+    }
+
+    /* package */ static class MediaExtractorStream
+                extends MediaCodecTest.ByteBufferStream implements Closeable {
+        public boolean mIsFloat;
+        public boolean mSawOutputEOS;
+        public MediaFormat mFormat;
+
+        private MediaExtractor mExtractor;
+
+        public MediaExtractorStream(
+                String mime,
+                MediaDataSource dataSource) throws Exception {
+            mExtractor = new MediaExtractor();
+            mExtractor.setDataSource(dataSource);
+            final int numTracks = mExtractor.getTrackCount();
+            // Single track?
+            // assertEquals("Number of tracks should be 1", 1, numTracks);
+            for (int i = 0; i < numTracks; ++i) {
+                final MediaFormat format = mExtractor.getTrackFormat(i);
+                final String actualMime = format.getString(MediaFormat.KEY_MIME);
+                if (mime.equals(actualMime)) {
+                    mExtractor.selectTrack(i);
+                    mFormat = format;
+                    break;
+                }
+            }
+            assertNotNull("MediaExtractor cannot find mime type " + mime, mFormat);
+            Integer actualEncoding = null;
+            try {
+                actualEncoding = mFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);
+            } catch (Exception e) {
+                ; // trying to get a non-existent key throws exception
+            }
+            mIsFloat = actualEncoding != null && actualEncoding == AudioFormat.ENCODING_PCM_FLOAT;
+        }
+
+        public MediaExtractorStream(
+                String mime,
+                MediaCodecTest.ByteBufferStream inputStream) throws Exception {
+            this(mime, new ByteBufferDataSource(inputStream));
+        }
+
+        @Override
+        public ByteBuffer read() throws IOException {
+            if (mSawOutputEOS) {
+                return null;
+            }
+
+            // To preserve codec-like behavior, we create ByteBuffers
+            // equal to the media sample size.
+            final long size = mExtractor.getSampleSize();
+            if (size >= 0) {
+                final ByteBuffer inputBuffer = ByteBuffer.allocate((int)size);
+                final int red = mExtractor.readSampleData(inputBuffer, 0 /* offset */); // sic
+                if (red >= 0) {
+                    assertEquals("position must be zero", 0, inputBuffer.position());
+                    assertEquals("limit must be read bytes", red, inputBuffer.limit());
+                    mExtractor.advance();
+                    return inputBuffer;
+                }
+            }
+            mSawOutputEOS = true;
+            return null;
+        }
+
+        @Override
+        public void close() throws IOException {
+            if (mExtractor != null) {
+                mExtractor.release();
+                mExtractor = null;
+            }
+            mFormat = null;
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            if (mExtractor != null) {
+                Log.w(TAG, "MediaExtractorStream wasn't closed");
+                mExtractor.release();
+            }
+            mFormat = null;
+        }
+    }
+
+    @SmallTest
+    public void testFlacIdentity() throws Exception {
+        final int PCM_FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
+        final int CHANNEL_COUNT = 2;
+        final int SAMPLES = PCM_FRAMES * CHANNEL_COUNT;
+        final int[] SAMPLE_RATES = {44100, 192000}; // ensure 192kHz supported.
+
+        for (int sampleRate : SAMPLE_RATES) {
+            final MediaFormat format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
+            format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
+            format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNEL_COUNT);
+
+            Log.d(TAG, "Trying sample rate: " + sampleRate
+                    + " channel count: " + CHANNEL_COUNT);
+            format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
+
+            // TODO: Add float mode when MediaExtractor supports float configuration.
+            final MediaCodecTest.PcmAudioBufferStream audioStream =
+                    new MediaCodecTest.PcmAudioBufferStream(
+                            SAMPLES, sampleRate, 1000 /* frequency */, 100 /* sweep */,
+                          false /* useFloat */);
+
+            final MediaCodecTest.MediaCodecStream rawToFlac =
+                    new MediaCodecTest.MediaCodecStream(
+                            new MediaCodecTest.ByteBufferInputStream(audioStream),
+                            format, true /* encode */);
+            final MediaExtractorStream flacToRaw =
+                    new MediaExtractorStream("audio/raw", rawToFlac);
+
+            // Note: the existence of signed zero (as well as NAN) may make byte
+            // comparisons invalid for floating point output. In our case, since the
+            // floats come through integer to float conversion, it does not matter.
+            assertEquals("Audio data not identical after compression",
+                audioStream.sizeInBytes(),
+                MediaCodecTest.compareStreams(new MediaCodecTest.ByteBufferInputStream(flacToRaw),
+                    new MediaCodecTest.ByteBufferInputStream(
+                            new MediaCodecTest.PcmAudioBufferStream(audioStream))));
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java b/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java
new file mode 100644
index 0000000..7058344
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for media heavy presubmit tests.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface MediaHeavyPresubmitTest {
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 4265a37..0d1796a 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -605,14 +605,14 @@
                 MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
         String widthTest = retrieverTest.extractMetadata(
                 MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
-        assertEquals("Different height", widthSrc,
+        assertEquals("Different width", widthSrc,
                 widthTest);
 
         String durationSrc = retrieverSrc.extractMetadata(
-                MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
+                MediaMetadataRetriever.METADATA_KEY_DURATION);
         String durationTest = retrieverTest.extractMetadata(
-                MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
-        assertEquals("Different height", durationSrc,
+                MediaMetadataRetriever.METADATA_KEY_DURATION);
+        assertEquals("Different duration", durationSrc,
                 durationTest);
 
         retrieverSrc.release();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
index 3143e48..a5461e7 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
@@ -128,6 +128,14 @@
                 ModularDrmTestType.V3_ASYNC_DRMPREPARED_TEST);
     }
 
+    @LargeTest
+    public void testCAR_CLEARKEY_AUDIO_DOWNLOADED_V5_ASYNC_CALLBACKS() throws Exception {
+        download(CENC_AUDIO_URL,
+                CENC_AUDIO_URL_DOWNLOADED,
+                RES_AUDIO,
+                ModularDrmTestType.V5_ASYNC_CALLBACKS_TEST);
+    }
+
     // helpers
 
     private void stream(Uri uri, Resolution res, ModularDrmTestType testType) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
index 9f083f2..c27b314 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
@@ -27,7 +27,9 @@
 import android.media.MediaDrm;
 import android.media.MediaPlayer2;
 import android.media.MediaPlayer2.DrmInfo;
+import android.media.MediaPlayer2.DrmPreparationInfo;
 import android.media.VideoSize;
+import android.media.MediaDrm.KeyRequest;
 import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.SystemClock;
@@ -152,6 +154,7 @@
         V2_SYNC_CONFIG_TEST,
         V3_ASYNC_DRMPREPARED_TEST,
         V4_SYNC_OFFLINE_KEY,
+        V5_ASYNC_CALLBACKS_TEST,
     }
 
     // TODO: After living on these tests for a while, we can consider grouping them based on
@@ -223,12 +226,14 @@
             case V1_ASYNC_TEST:
             case V2_SYNC_CONFIG_TEST:
             case V3_ASYNC_DRMPREPARED_TEST:
+            case V5_ASYNC_CALLBACKS_TEST:
                 playLoadedModularDrmVideo_Generic(file, width, height, playTime, testType);
                 break;
 
             case V4_SYNC_OFFLINE_KEY:
                 playLoadedModularDrmVideo_V4_offlineKey(file, width, height, playTime);
                 break;
+
         }
     }
 
@@ -303,6 +308,13 @@
                 case V3_ASYNC_DRMPREPARED_TEST:
                     preparePlayerAndDrm_V3_asyncDrmSetupPlusDrmPreparedListener(dsd);
                     break;
+
+                case V5_ASYNC_CALLBACKS_TEST:
+                    preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(dsd);
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("invalid test type: " + testType);
             }
 
         } catch (IOException e) {
@@ -328,6 +340,7 @@
 
         try {
             Log.v(TAG, "playLoadedVideo: releaseDrm");
+            mPlayer.reset();
             mPlayer.releaseDrm(dsd);
         } catch (Exception e) {
             e.printStackTrace();
@@ -354,15 +367,16 @@
     private void preparePlayerAndDrm_V1_asyncDrmSetup(DataSourceDesc dsd) throws InterruptedException {
         final AtomicBoolean asyncSetupDrmError = new AtomicBoolean(false);
 
-        mPlayer.registerDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+        mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
             @Override
-            public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2, DrmInfo drmInfo) {
+            public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+                    DrmInfo drmInfo) {
                 Log.v(TAG, "preparePlayerAndDrm_V1: onDrmInfo" + drmInfo);
                 if (dsd != dsd2) {
                     Log.e(TAG, "preparePlayerAndDrm_V1: onDrmInfo dsd mismatch");
                     asyncSetupDrmError.set(true);
                     mOnDrmInfoCalled.signal();
-                    return;
+                    return null;
                 }
 
                 // in the callback (async mode) so handling exceptions here
@@ -376,6 +390,7 @@
 
                 mOnDrmInfoCalled.signal();
                 Log.v(TAG, "preparePlayerAndDrm_V1: onDrmInfo done!");
+                return null;
             }
         });
 
@@ -396,9 +411,9 @@
     private void preparePlayerAndDrm_V2_syncDrmSetupPlusConfig(DataSourceDesc dsd)
             throws Exception {
         final AtomicBoolean drmConfigError = new AtomicBoolean(false);
-        mPlayer.setOnDrmConfigHelper(new MediaPlayer2.OnDrmConfigHelper() {
+        mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
             @Override
-            public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2) {
+            public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
                 if (dsd != dsd2) {
                     Log.e(TAG, "preparePlayerAndDrm_V2: onDrmConfig dsd mismatch");
                     drmConfigError.set(true);
@@ -409,15 +424,13 @@
                 String securityLevelProperty = "securityLevel";
 
                 try {
-                    String level = mp.getDrmPropertyString(dsd2, securityLevelProperty);
+                    String level = drmObj.getPropertyString(securityLevelProperty);
                     Log.v(TAG, "preparePlayerAndDrm_V2: getDrmPropertyString: "
                             + securityLevelProperty + " -> " + level);
-                    mp.setDrmPropertyString(dsd2, securityLevelProperty, widevineSecurityLevel3);
-                    level = mp.getDrmPropertyString(dsd2, securityLevelProperty);
+                    drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
+                    level = drmObj.getPropertyString(securityLevelProperty);
                     Log.v(TAG, "preparePlayerAndDrm_V2: getDrmPropertyString: "
                             + securityLevelProperty + " -> " + level);
-                } catch (MediaPlayer2.NoDrmSchemeException e) {
-                    Log.v(TAG, "preparePlayerAndDrm_V2: NoDrmSchemeException");
                 } catch (Exception e) {
                     Log.v(TAG, "preparePlayerAndDrm_V2: onDrmConfig EXCEPTION " + e);
                 }
@@ -448,9 +461,10 @@
             throws InterruptedException {
         final AtomicBoolean asyncSetupDrmError = new AtomicBoolean(false);
 
-        mPlayer.registerDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+        mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
             @Override
-            public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2, DrmInfo drmInfo) {
+            public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+                    DrmInfo drmInfo) {
                 Log.v(TAG, "preparePlayerAndDrm_V3: onDrmInfo" + drmInfo);
 
                 // DRM preperation
@@ -462,7 +476,7 @@
                     mOnDrmInfoCalled.signal();
                     // we won't call prepareDrm anymore but need to get passed the wait
                     mOnDrmPreparedCalled.signal();
-                    return;
+                    return null;
                 }
 
                 // setting up with the first supported UUID
@@ -475,10 +489,12 @@
 
                 mOnDrmInfoCalled.signal();
                 Log.v(TAG, "preparePlayerAndDrm_V3: onDrmInfo done!");
+                return null;
             }
 
             @Override
-            public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+            public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status,
+                    byte[] keySetId) {
                 Log.v(TAG, "preparePlayerAndDrm_V3: onDrmPrepared status: " + status);
 
                 if (dsd != dsd2) {
@@ -524,6 +540,116 @@
         }
     }
 
+    private void preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(DataSourceDesc dsd)
+            throws InterruptedException {
+        final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+
+        mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+            @Override
+            public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+                    DrmInfo drmInfo) {
+                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo" + drmInfo);
+
+                // DRM preparation
+                UUID drmScheme = CLEARKEY_SCHEME_UUID;
+                List<UUID> supportedSchemes = drmInfo.getSupportedSchemes();
+                if (dsd != dsd2 || supportedSchemes.isEmpty()) {
+                    String msg = dsd != dsd2 ? "dsd mismatch" : "No supportedSchemes";
+                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmInfo " + msg);
+                    drmCallbackError.set(true);
+                    return null;
+                }
+
+                // setting up with the first supported UUID
+                // instead of supportedSchemes[0] in GTS
+                DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder();
+                drmBuilder.setUuid(drmScheme);
+                drmBuilder.setMimeType("cenc");
+                drmBuilder.setKeyType(MediaDrm.KEY_TYPE_STREAMING);
+
+                byte[] psshData = drmInfo.getPssh().get(drmScheme);
+                byte[] initData;
+                // diverging from GTS
+                if (psshData == null) {
+                    initData = mClearKeyPssh;
+                    Log.d(TAG, "preparePlayerAndDrm_V5: CLEARKEY scheme not found in PSSH."
+                            + " Using default data.");
+                } else {
+                    // Can skip conversion if ClearKey adds support for BMFF initData b/64863112
+                    initData = makeCencPSSH(drmScheme, psshData);
+                }
+                drmBuilder.setInitData(initData);
+                Log.d(TAG, "preparePlayerAndDrm_V5: initData[" + drmScheme + "]: "
+                        + Arrays.toString(initData));
+
+                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo done!");
+                return drmBuilder.build();
+            }
+
+            @Override
+            public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
+                if (dsd != dsd2) {
+                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmConfig dsd mismatch");
+                    drmCallbackError.set(true);
+                    return;
+                }
+
+                String widevineSecurityLevel3 = "L3";
+                String securityLevelProperty = "securityLevel";
+
+                try {
+                    String level = drmObj.getPropertyString(securityLevelProperty);
+                    Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
+                            + securityLevelProperty + " -> " + level);
+                    drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
+                    level = drmObj.getPropertyString(securityLevelProperty);
+                    Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
+                            + securityLevelProperty + " -> " + level);
+                } catch (Exception e) {
+                    Log.v(TAG, "preparePlayerAndDrm_V5: onDrmConfig EXCEPTION " + e);
+                }
+            }
+
+            @Override
+            public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest req) {
+                byte[][] clearKeys = new byte[][] { CLEAR_KEY_CENC };
+                byte[] response = createKeysResponse(req, clearKeys);
+                return response;
+            }
+
+            @Override
+            public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status,
+                    byte[] keySetId) {
+                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmPrepared status: " + status);
+                String errMsg = null;
+                if (dsd != dsd2) {
+                    errMsg = "dsd mismatch";
+                }
+                if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS) {
+                    errMsg = "drm prepare failed";
+                }
+                if (keySetId != null && keySetId.length > 0) {
+                    errMsg = "unexpected keySetId";
+                }
+                if (errMsg != null) {
+                    drmCallbackError.set(true);
+                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmPrepared " + errMsg);
+                }
+            }
+        });
+
+        Log.v(TAG, "preparePlayerAndDrm_V5: calling prepare()");
+        mPlayer.prepare();
+
+        // Waiting till the player is prepared
+        mOnPreparedCalled.waitForSignal();
+
+        // handle error (async) in main thread rather than callbacks
+        if (drmCallbackError.get()) {
+            fail("preparePlayerAndDrm_V5: setupDrm");
+        }
+    }
+
     private void playLoadedModularDrmVideo_V4_offlineKey(final Uri file, final Integer width,
             final Integer height, int playTime) throws Exception {
         final float volume = 0.5f;
@@ -680,11 +806,11 @@
 
                     if (prepareDrm) {
                         final Monitor drmPrepared = new Monitor();
-                        mPlayer.registerDrmEventCallback(
+                        mPlayer.setDrmEventCallback(
                                 mExecutor, new MediaPlayer2.DrmEventCallback() {
                             @Override
-                            public void onDrmPrepared(
-                                    MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+                            public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2,
+                                    int status, byte[] keySetId) {
                                 if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS
                                         || dsd != dsd2) {
                                     prepareDrmFailed.set(true);
@@ -784,11 +910,11 @@
                 Log.d(TAG, "setupDrmRestore: selected " + drmScheme);
 
                 final Monitor drmPrepared = new Monitor();
-                mPlayer.registerDrmEventCallback(
+                mPlayer.setDrmEventCallback(
                         mExecutor, new MediaPlayer2.DrmEventCallback() {
                     @Override
                     public void onDrmPrepared(
-                            MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+                            MediaPlayer2 mp, DataSourceDesc dsd2, int status, byte[] keySetId) {
                         if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS
                                 || dsd != dsd2) {
                             prepareDrmFailed.set(true);
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index 799eef0..3c780ca 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -956,7 +956,7 @@
             return; // skip
         }
 
-        int resid = R.raw.testvideo;
+        int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
         if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
             return;  // skip
         }
@@ -1053,7 +1053,7 @@
             return; // skip
         }
 
-        int resid = R.raw.testvideo;
+        int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
         if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
             return;  // skip
         }
@@ -1160,7 +1160,7 @@
             return; // skip
         }
 
-        int resid = R.raw.testvideo;
+        int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
         if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
             return;  // skip
         }
@@ -1184,22 +1184,22 @@
             public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
                 if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_START) {
                     if (dsd == dsd2) {
-                        Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_START dsd2");
+                        Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_START dsd2");
                         onStart2Called.signal();
                     } else {
-                        Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_START other");
+                        Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_START other");
                         onStartCalled.signal();
                     }
                 } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_END) {
                     if (dsd == dsd2) {
-                        Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_END dsd2");
+                        Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_END dsd2");
                         onCompletion2Called.signal();
                     } else {
-                        Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_END other");
+                        Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_END other");
                         mOnCompletionCalled.signal();
                     }
                 } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_LIST_END) {
-                    Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_LIST_END");
+                    Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_LIST_END");
                     onListCompletionCalled.signal();
                 }
             }
@@ -2053,6 +2053,7 @@
         Thread.sleep(10000);
         assertTrue("MediaPlayer2 should still be playing",
                 mPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING);
+        mPlayer.unregisterEventCallback(ecb);
         mPlayer.reset();
         assertEquals("wrong number of repetitions", 1, mOnCompletionCalled.getNumSignal());
         return 1;
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index e016730..3db1d13 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -15,18 +15,15 @@
  */
 package android.media.cts;
 
-
-import android.media.cts.R;
-
-import android.media.MediaRecorder;
-import android.media.MediaPlayer;
-import android.platform.test.annotations.AppModeFull;
-import android.view.SurfaceHolder;
-import android.test.ActivityInstrumentationTestCase2;
-import android.os.Environment;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.os.Environment;
+import android.platform.test.annotations.AppModeFull;
+import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
+import android.view.SurfaceHolder;
 
 import java.util.Random;
 
@@ -41,6 +38,7 @@
  * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
  * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
  */
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
     private static final String TAG = "MediaRandomTest";
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index f1ad46c..042881c 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -675,6 +675,7 @@
         assertTrue(MediaRecorder.AudioSource.VOICE_RECOGNITION <= max);
         assertTrue(MediaRecorder.AudioSource.VOICE_UPLINK <= max);
         assertTrue(MediaRecorder.AudioSource.UNPROCESSED <= max);
+        assertTrue(MediaRecorder.AudioSource.VOICE_PERFORMANCE <= max);
     }
 
     public void testRecorderAudio() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
index 52da641..3eb1ab4 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -18,8 +18,6 @@
 
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Bundle;
 import android.os.Environment;
 import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
@@ -27,8 +25,6 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaScannerNotificationTest extends AndroidTestCase {
@@ -50,13 +46,7 @@
         String [] temps = new String[] { "avi", "gif", "jpg", "dat", "mp3", "mp4", "txt" };
         String tmpPath = createTempFiles(temps);
 
-        Bundle args = new Bundle();
-        args.putString("volume", "external");
-        Intent i = new Intent("android.media.IMediaScannerService").putExtras(args);
-        i.setClassName("com.android.providers.media",
-                "com.android.providers.media.MediaScannerService");
-        mContext.startService(i);
-
+        MediaScannerTest.startMediaScan();
         startedReceiver.waitForBroadcast();
         finishedReceiver.waitForBroadcast();
 
@@ -71,7 +61,7 @@
         }
         startedReceiver.reset();
         finishedReceiver.reset();
-        mContext.startService(i);
+        MediaScannerTest.startMediaScan();
         startedReceiver.waitForBroadcast();
         finishedReceiver.waitForBroadcast();
 
@@ -82,7 +72,7 @@
         // scan one more time just to clean everything up nicely
         startedReceiver.reset();
         finishedReceiver.reset();
-        mContext.startService(i);
+        MediaScannerTest.startMediaScan();
         startedReceiver.waitForBroadcast();
         finishedReceiver.waitForBroadcast();
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index 72ed274..1b0d6fc 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -19,7 +19,6 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentUris;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -29,13 +28,13 @@
 import android.media.MediaScannerConnection;
 import android.media.MediaScannerConnection.MediaScannerConnectionClient;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.RequiresDevice;
 import android.provider.MediaStore;
+import android.support.test.InstrumentationRegistry;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
@@ -372,6 +371,10 @@
     }
 
     private void canonicalizeTest(int resId) throws Exception {
+        // erase all audio files that might confuse us below
+        mContext.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
+                null, null);
+
         // write file and scan to insert into database
         String fileDir = Environment.getExternalStorageDirectory() + "/"
                 + getClass().getCanonicalName() + "/canonicaltest-" + System.currentTimeMillis();
@@ -612,6 +615,14 @@
         }
     }
 
+    static void startMediaScan() {
+        // Ugh, the best proxy we have is pretending that it was just mounted
+        InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
+                "am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_VOLUME "
+                        + "--receiver-include-background -d "
+                        + Uri.fromFile(Environment.getExternalStorageDirectory()));
+    }
+
     private void startMediaScanAndWait() throws InterruptedException {
         ScannerNotificationReceiver finishedReceiver = new ScannerNotificationReceiver(
                 Intent.ACTION_MEDIA_SCANNER_FINISHED);
@@ -619,12 +630,7 @@
         finishedIntentFilter.addDataScheme("file");
         mContext.registerReceiver(finishedReceiver, finishedIntentFilter);
 
-        Bundle args = new Bundle();
-        args.putString("volume", "external");
-        Intent i = new Intent("android.media.IMediaScannerService").putExtras(args);
-        i.setClassName("com.android.providers.media",
-                "com.android.providers.media.MediaScannerService");
-        mContext.startService(i);
+        startMediaScan();
 
         finishedReceiver.waitForBroadcast();
         mContext.unregisterReceiver(finishedReceiver);
@@ -683,6 +689,7 @@
         }
 
         public void onScanCompleted(String path, Uri uri) {
+            Log.v("MediaScannerTest", "onScanCompleted for " + path + " to " + uri);
             mediaPath = path;
             if (uri != null) {
                 mediaUri = uri;
diff --git a/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java b/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java
new file mode 100644
index 0000000..d8a34a0
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.MediaSession2Service;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
+import android.os.CountDownTimer;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link MediaSession2Service}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaSession2ServiceTest {
+    private static final long TIMEOUT_MS = 3000L;
+
+    private static HandlerExecutor sHandlerExecutor;
+    private final List<MediaController2> mControllers = new ArrayList<>();
+    private Context mContext;
+    private Session2Token mToken;
+
+    @BeforeClass
+    public static void setUpThread() {
+        synchronized (MediaSession2ServiceTest.class) {
+            if (sHandlerExecutor != null) {
+                return;
+            }
+            HandlerThread handlerThread = new HandlerThread("MediaSession2ServiceTest");
+            handlerThread.start();
+            sHandlerExecutor = new HandlerExecutor(handlerThread.getLooper());
+            StubMediaSession2Service.setHandlerExecutor(sHandlerExecutor);
+        }
+    }
+
+    @AfterClass
+    public static void cleanUpThread() {
+        synchronized (MediaSession2Test.class) {
+            if (sHandlerExecutor == null) {
+                return;
+            }
+            StubMediaSession2Service.setHandlerExecutor(null);
+            sHandlerExecutor.getLooper().quitSafely();
+            sHandlerExecutor = null;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mToken = new Session2Token(mContext,
+                new ComponentName(mContext, StubMediaSession2Service.class));
+    }
+
+    @After
+    public void cleanUp() throws Exception {
+        for (MediaController2 controller : mControllers) {
+            controller.close();
+        }
+        mControllers.clear();
+
+        StubMediaSession2Service.setTestInjector(null);
+    }
+
+    /**
+     * Tests whether {@link MediaSession2Service#onGetPrimarySession()} is called whenever a
+     * controller is created with the service's token.
+     */
+    @Test
+    public void testOnGetPrimarySession() throws InterruptedException {
+        MediaController2 controller1 = createConnectedController(mToken);
+        MediaController2 controller2 = createConnectedController(mToken);
+        assertNotEquals(mToken, controller1.getConnectedSessionToken());
+        assertEquals(Session2Token.TYPE_SESSION,
+                controller1.getConnectedSessionToken().getType());
+        assertEquals(controller1.getConnectedSessionToken(),
+                controller2.getConnectedSessionToken());
+    }
+
+    /**
+     * Tests whether {@link MediaSession2Service#onGetPrimarySession()} is called whenever a
+     * controller is created with the service's token.
+     */
+    @Test
+    public void testOnGetPrimarySession_multipleSessions() throws InterruptedException {
+        final List<Session2Token> tokens = new ArrayList<>();
+        StubMediaSession2Service.setTestInjector(
+                new StubMediaSession2Service.TestInjector() {
+                    @Override
+                    MediaSession2 onGetPrimarySession() {
+                        MediaSession2 session = new MediaSession2.Builder(mContext)
+                                .setId("testOnGetPrimarySession_multipleSession"
+                                        + System.currentTimeMillis())
+                                .setSessionCallback(sHandlerExecutor, new SessionCallback())
+                                .build();
+                        tokens.add(session.getSessionToken());
+                        return session;
+                    }
+                });
+
+        MediaController2 controller1 = createConnectedController(mToken);
+        MediaController2 controller2 = createConnectedController(mToken);
+
+        assertNotEquals(mToken, controller1.getConnectedSessionToken());
+        assertNotEquals(mToken, controller2.getConnectedSessionToken());
+
+        assertNotEquals(controller1.getConnectedSessionToken(),
+                controller2.getConnectedSessionToken());
+        assertEquals(2, tokens.size());
+        assertEquals(tokens.get(0), controller1.getConnectedSessionToken());
+        assertEquals(tokens.get(1), controller2.getConnectedSessionToken());
+    }
+
+    @Test
+    public void testAllControllersDisconnected_oneSession() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        StubMediaSession2Service.setTestInjector(
+                new StubMediaSession2Service.TestInjector() {
+                    @Override
+                    void onServiceDestroyed() {
+                        latch.countDown();
+                    }
+                });
+        MediaController2 controller1 = createConnectedController(mToken);
+        MediaController2 controller2 = createConnectedController(mToken);
+        controller1.close();
+        controller2.close();
+
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testAllControllersDisconnected_multipleSession() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        StubMediaSession2Service.setTestInjector(new StubMediaSession2Service.TestInjector() {
+            @Override
+            MediaSession2 onGetPrimarySession() {
+                return new MediaSession2.Builder(mContext)
+                        .setId("testAllControllersDisconnected_multipleSession"
+                                + System.currentTimeMillis())
+                        .setSessionCallback(sHandlerExecutor, new SessionCallback())
+                        .build();
+            }
+
+            @Override
+            void onServiceDestroyed() {
+                latch.countDown();
+            }
+        });
+
+        MediaController2 controller1 = createConnectedController(mToken);
+        MediaController2 controller2 = createConnectedController(mToken);
+        controller1.close();
+        controller2.close();
+
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testGetSessions() throws InterruptedException {
+        MediaController2 controller = createConnectedController(mToken);
+        MediaSession2Service service = StubMediaSession2Service.getInstance();
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setId("testGetSessions")
+                .setSessionCallback(sHandlerExecutor, new SessionCallback())
+                .build()) {
+            service.addSession(session);
+            List<MediaSession2> sessions = service.getSessions();
+            assertTrue(sessions.contains(session));
+            assertEquals(2, sessions.size());
+
+            service.removeSession(session);
+            sessions = service.getSessions();
+            assertFalse(sessions.contains(session));
+        }
+    }
+
+    @Test
+    public void testAddSessions_removedWhenClose() throws InterruptedException {
+        MediaController2 controller = createConnectedController(mToken);
+        MediaSession2Service service = StubMediaSession2Service.getInstance();
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setId("testAddSessions_removedWhenClose")
+                .setSessionCallback(sHandlerExecutor, new SessionCallback())
+                .build()) {
+            service.addSession(session);
+            List<MediaSession2> sessions = service.getSessions();
+            assertTrue(sessions.contains(session));
+            assertEquals(2, sessions.size());
+
+            session.close();
+            sessions = service.getSessions();
+            assertFalse(sessions.contains(session));
+        }
+    }
+
+    @Test
+    public void testOnUpdateNotification() throws InterruptedException {
+        MediaController2 controller = createConnectedController(mToken);
+        MediaSession2Service service = StubMediaSession2Service.getInstance();
+        MediaSession2 primarySession = service.getSessions().get(0);
+        CountDownLatch latch = new CountDownLatch(2);
+
+        StubMediaSession2Service.setTestInjector(
+                new StubMediaSession2Service.TestInjector() {
+                    @Override
+                    MediaSession2Service.MediaNotification onUpdateNotification(
+                            MediaSession2 session) {
+                        assertEquals(primarySession, session);
+                        switch ((int) latch.getCount()) {
+                            case 2:
+
+                                break;
+                            case 1:
+                        }
+                        latch.countDown();
+                        return super.onUpdateNotification(session);
+                    }
+                });
+
+        primarySession.setPlaybackActive(true);
+        primarySession.setPlaybackActive(false);
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    private MediaController2 createConnectedController(Session2Token token)
+            throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        MediaController2 controller = new MediaController2(mContext, token, sHandlerExecutor,
+                new MediaController2.ControllerCallback() {
+                    @Override
+                    public void onConnected(MediaController2 controller,
+                            Session2CommandGroup allowedCommands) {
+                        latch.countDown();
+                        super.onConnected(controller, allowedCommands);
+                    }
+                });
+        mControllers.add(controller);
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        return controller;
+    }
+
+    private static class SessionCallback extends MediaSession2.SessionCallback {
+        @Override
+        public Session2CommandGroup onConnect(MediaSession2 session,
+                MediaSession2.ControllerInfo controller) {
+            if (controller.getUid() == Process.myUid()) {
+                return new Session2CommandGroup.Builder().build();
+            }
+            return null;
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaSession2Test.java b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
new file mode 100644
index 0000000..9738f65
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link android.media.MediaSession2}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaSession2Test {
+    private static final long WAIT_TIME_MS = 300L;
+
+    static Handler sHandler;
+    static Executor sHandlerExecutor;
+    final static Object sTestLock = new Object();
+
+    private Context mContext;
+
+    @BeforeClass
+    public static void setUpThread() {
+        synchronized (MediaSession2Test.class) {
+            if (sHandler != null) {
+                return;
+            }
+            HandlerThread handlerThread = new HandlerThread("MediaSessionTestBase");
+            handlerThread.start();
+            sHandler = new Handler(handlerThread.getLooper());
+            sHandlerExecutor = (runnable) -> {
+                Handler handler;
+                synchronized (MediaSession2Test.class) {
+                    handler = sHandler;
+                }
+                if (handler != null) {
+                    handler.post(() -> {
+                        synchronized (sTestLock) {
+                            runnable.run();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    @AfterClass
+    public static void cleanUpThread() {
+        synchronized (MediaSession2Test.class) {
+            if (sHandler == null) {
+                return;
+            }
+            sHandler.getLooper().quitSafely();
+            sHandler = null;
+            sHandlerExecutor = null;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void testBuilder_setIllegalArguments() {
+        MediaSession2.Builder builder;
+        try {
+            builder = new MediaSession2.Builder(null);
+            fail("null context shouldn't be allowed");
+        } catch (IllegalArgumentException e) {
+            // expected. pass-through
+        }
+        try {
+            builder = new MediaSession2.Builder(mContext);
+            builder.setId(null);
+            fail("null id shouldn't be allowed");
+        } catch (IllegalArgumentException e) {
+            // expected. pass-through
+        }
+    }
+
+    @Test
+    public void testBuilder_createSessionWithoutId() {
+        try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
+            assertEquals("", session.getSessionId());
+        }
+    }
+
+    @Test
+    public void testBuilder_createSessionWithDupId() {
+        final String dupSessionId = "TEST_SESSION_DUP_ID";
+        MediaSession2.Builder builder = new MediaSession2.Builder(mContext).setId(dupSessionId);
+        try (
+            MediaSession2 session1 = builder.build();
+            MediaSession2 session2 = builder.build()
+        ) {
+            fail("Duplicated id shouldn't be allowed");
+        } catch (IllegalStateException e) {
+            // expected. pass-through
+        }
+    }
+
+    @Test
+    public void testSession2Token() {
+        try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
+            Session2Token token = session.getSessionToken();
+            assertEquals(Process.myUid(), token.getUid());
+            assertEquals(mContext.getPackageName(), token.getPackageName());
+            assertNull(token.getServiceName());
+            assertEquals(Session2Token.TYPE_SESSION, token.getType());
+        }
+    }
+
+    @Test
+    public void testCallback_onConnect_onDisconnect() throws Exception {
+        Session2Callback sessionCallback = new Session2Callback();
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+            // Test onConnect
+            Controller2Callback controllerCallback = new Controller2Callback();
+            MediaController2 controller = new MediaController2(
+                    mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+            assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+            assertEquals(session, sessionCallback.mSession);
+            MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+            // Test onDisconnect
+            controller.close();
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+            assertTrue(sessionCallback.awaitOnDisconnect(WAIT_TIME_MS));
+            assertEquals(session, sessionCallback.mSession);
+            assertEquals(controllerInfo, sessionCallback.mController);
+        }
+    }
+
+    @Test
+    public void testCallback_onSessionCommand() {
+        Session2Callback sessionCallback = new Session2Callback();
+
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+            Controller2Callback controllerCallback = new Controller2Callback();
+            MediaController2 controller = new MediaController2(
+                    mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+            // Wait for connection
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+            assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+            MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+            // Test onSessionCommand
+            String commandStr = "test_command";
+            String commandExtraKey = "test_extra_key";
+            String commandExtraValue = "test_extra_value";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key";
+            String commandArgValue = "test_arg_value";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            controller.sendSessionCommand(command, commandArg);
+
+            assertTrue(sessionCallback.awaitOnSessionCommand(WAIT_TIME_MS));
+            assertEquals(session, sessionCallback.mSession);
+            assertEquals(controllerInfo, sessionCallback.mController);
+            assertEquals(commandStr, sessionCallback.mCommand.getCustomCommand());
+            assertEquals(commandExtraValue,
+                    sessionCallback.mCommand.getExtras().getString(commandExtraKey));
+            assertEquals(commandArgValue, sessionCallback.mCommandArgs.getString(commandArgKey));
+
+            controller.close();
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testCallback_onCommandResult() {
+        Session2Callback sessionCallback = new Session2Callback();
+
+        int resultCode = 100;
+        String commandResultKey = "test_result_key";
+        String commandResultValue = "test_result_value";
+        Bundle resultData = new Bundle();
+        resultData.putString(commandResultKey, commandResultValue);
+        Session2Command.Result commandResult = new Session2Command.Result(resultCode, resultData);
+
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+            Controller2Callback controllerCallback = new Controller2Callback() {
+                @Override
+                public Session2Command.Result onSessionCommand(MediaController2 controller,
+                        Session2Command command, Bundle args) {
+                    return commandResult;
+                }
+            };
+            MediaController2 controller = new MediaController2(
+                    mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+            // Wait for connection
+            assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+            MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+            // Test onCommandResult
+            String commandStr = "test_command";
+            String commandExtraKey = "test_extra_key";
+            String commandExtraValue = "test_extra_value";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key";
+            String commandArgValue = "test_arg_value";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            session.sendSessionCommand(controllerInfo, command, commandArg);
+
+            assertTrue(sessionCallback.awaitOnCommandResult(WAIT_TIME_MS));
+            assertEquals(session, sessionCallback.mSession);
+            assertEquals(controllerInfo, sessionCallback.mController);
+            assertEquals(resultCode, sessionCallback.mCommandResult.getResultCode());
+            assertEquals(commandResultValue,
+                    sessionCallback.mCommandResult.getResultData().getString(commandResultKey));
+
+            controller.close();
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testSetPlaybackActive() {
+        final boolean testInitialPlaybackActive = true;
+        final boolean testPlaybackActive = false;
+        Session2Callback sessionCallback = new Session2Callback();
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+            session.setPlaybackActive(testInitialPlaybackActive);
+
+            Controller2Callback controllerCallback = new Controller2Callback();
+            MediaController2 controller = new MediaController2(mContext, session.getSessionToken(),
+                    sHandlerExecutor, controllerCallback);
+            // Wait for connection
+            assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+            // Check initial value
+            assertEquals(testInitialPlaybackActive, controller.isPlaybackActive());
+
+            // Change playback active change and wait for changes
+            session.setPlaybackActive(testPlaybackActive);
+            assertTrue(controllerCallback.awaitOnPlaybackActiveChanged(WAIT_TIME_MS));
+
+            assertEquals(testPlaybackActive, controllerCallback.getNotifiedPlaybackActive());
+            assertEquals(testPlaybackActive, controller.isPlaybackActive());
+
+            controller.close();
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    @Test
+    public void testCancelSessionCommand() {
+        Session2Callback sessionCallback = new Session2Callback();
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+            Controller2Callback controllerCallback = new Controller2Callback();
+            MediaController2 controller = new MediaController2(mContext, session.getSessionToken(),
+                    sHandlerExecutor, controllerCallback);
+            // Wait for connection
+            assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+            MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+            String commandStr = "test_command_";
+            String commandExtraKey = "test_extra_key_";
+            String commandExtraValue = "test_extra_value_";
+            Bundle commandExtra = new Bundle();
+            commandExtra.putString(commandExtraKey, commandExtraValue);
+            Session2Command command = new Session2Command(commandStr, commandExtra);
+
+            String commandArgKey = "test_arg_key_";
+            String commandArgValue = "test_arg_value_";
+            Bundle commandArg = new Bundle();
+            commandArg.putString(commandArgKey, commandArgValue);
+            synchronized (sTestLock) {
+                Object token = session.sendSessionCommand(controllerInfo, command, commandArg);
+                session.cancelSessionCommand(controllerInfo, token);
+            }
+            assertTrue(sessionCallback.awaitOnCommandResult(WAIT_TIME_MS));
+            assertEquals(Session2Command.RESULT_INFO_SKIPPED,
+                    sessionCallback.mCommandResult.getResultCode());
+
+            controller.close();
+            assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+        }
+    }
+
+    class Controller2Callback extends MediaController2.ControllerCallback {
+        private final CountDownLatch mOnConnectedLatch = new CountDownLatch(1);
+        private final CountDownLatch mOnDisconnectedLatch = new CountDownLatch(1);
+        private final CountDownLatch mOnPlaybackActiveChangedLatch = new CountDownLatch(1);
+
+        private boolean mPlaybackActive;
+
+        @Override
+        public void onConnected(MediaController2 controller,
+                Session2CommandGroup allowedCommands) {
+            mOnConnectedLatch.countDown();
+        }
+
+        @Override
+        public void onDisconnected(MediaController2 controller) {
+            mOnDisconnectedLatch.countDown();
+        }
+
+        @Override
+        public void onPlaybackActiveChanged(MediaController2 controller, boolean playbackActive) {
+            mPlaybackActive = playbackActive;
+            mOnPlaybackActiveChangedLatch.countDown();
+        }
+
+        public boolean awaitOnConnected(long waitTimeMs) {
+            try {
+                return mOnConnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnDisconnected(long waitTimeMs) {
+            try {
+                return mOnDisconnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnPlaybackActiveChanged(long waitTimeMs) {
+            try {
+                return mOnPlaybackActiveChangedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean getNotifiedPlaybackActive() {
+            return mPlaybackActive;
+        }
+    }
+
+    class Session2Callback extends MediaSession2.SessionCallback {
+        private final CountDownLatch mOnConnectLatch = new CountDownLatch(1);
+        private final CountDownLatch mOnDisconnectLatch = new CountDownLatch(1);
+        private final CountDownLatch mOnSessionCommandLatch = new CountDownLatch(1);
+        private final CountDownLatch mOnCommandResultLatch = new CountDownLatch(1);
+
+        MediaSession2 mSession;
+        MediaSession2.ControllerInfo mController;
+        Session2Command mCommand;
+        Bundle mCommandArgs;
+        Session2Command.Result mCommandResult;
+
+        @Override
+        public Session2CommandGroup onConnect(MediaSession2 session,
+                MediaSession2.ControllerInfo controller) {
+            if (controller.getUid() != Process.myUid()) {
+                return null;
+            }
+            mSession = session;
+            mController = controller;
+            mOnConnectLatch.countDown();
+            return new Session2CommandGroup.Builder().build();
+        }
+
+        @Override
+        public void onDisconnected(MediaSession2 session, MediaSession2.ControllerInfo controller) {
+            if (controller.getUid() != Process.myUid()) {
+                return;
+            }
+            mSession = session;
+            mController = controller;
+            mOnDisconnectLatch.countDown();
+        }
+
+        @Override
+        public Session2Command.Result onSessionCommand(MediaSession2 session,
+                MediaSession2.ControllerInfo controller, Session2Command command, Bundle args) {
+            if (controller.getUid() != Process.myUid()) {
+                return null;
+            }
+            mSession = session;
+            mController = controller;
+            mCommand = command;
+            mCommandArgs = args;
+            mOnSessionCommandLatch.countDown();
+
+            int resultCode = 100;
+            String commandResultKey = "test_result_key";
+            String commandResultValue = "test_result_value";
+            Bundle resultData = new Bundle();
+            resultData.putString(commandResultKey, commandResultValue);
+            Session2Command.Result commandResult =
+                    new Session2Command.Result(resultCode, resultData);
+            return commandResult;
+        }
+
+        @Override
+        public void onCommandResult(MediaSession2 session, MediaSession2.ControllerInfo controller,
+                Object token, Session2Command command, Session2Command.Result result) {
+            if (controller.getUid() != Process.myUid()) {
+                return;
+            }
+            mSession = session;
+            mController = controller;
+            mCommand = command;
+            mCommandResult = result;
+            mOnCommandResultLatch.countDown();
+        }
+
+        public boolean awaitOnConnect(long waitTimeMs) {
+            try {
+                return mOnConnectLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnDisconnect(long waitTimeMs) {
+            try {
+                return mOnDisconnectLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnSessionCommand(long waitTimeMs) {
+            try {
+                return mOnSessionCommandLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitOnCommandResult(long waitTimeMs) {
+            try {
+                return mOnCommandResultLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index 926abd8..c38f3d0 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -22,6 +22,9 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.media.MediaSession2;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
@@ -29,14 +32,17 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.UserHandle;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
 import android.view.KeyEvent;
+import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
 @AppModeFull(reason = "TODO: evaluate and port to instant")
@@ -54,6 +60,11 @@
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
     }
 
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
     public void testGetActiveSessions() throws Exception {
         try {
             List<MediaController> controllers = mSessionManager.getActiveSessions(null);
@@ -114,10 +125,7 @@
             // events directly to the audio service to change the system volume.
             return;
         }
-
-        HandlerThread handlerThread = new HandlerThread(TAG);
-        handlerThread.start();
-        Handler handler = new Handler(handlerThread.getLooper());
+        Handler handler = createHandler();
 
         // Ensure that the listener is called for long-press.
         VolumeKeyLongPressListener listener = new VolumeKeyLongPressListener(3, handler);
@@ -144,13 +152,12 @@
         injectInputEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
         assertFalse(listener.mCountDownLatch.await(WAIT_MS, TimeUnit.MILLISECONDS));
         assertEquals(listener.mKeyEvents.size(), 0);
+
+        removeHandler(handler);
     }
 
     public void testSetOnMediaKeyListener() throws Exception {
-        HandlerThread handlerThread = new HandlerThread(TAG);
-        handlerThread.start();
-        Handler handler = new Handler(handlerThread.getLooper());
-
+        Handler handler = createHandler();
         MediaSession session = null;
         try {
             session = new MediaSession(getInstrumentation().getTargetContext(), TAG);
@@ -210,14 +217,13 @@
             if (session != null) {
                 session.release();
             }
+            removeHandler(handler);
         }
     }
 
     public void testRemoteUserInfo() throws Exception {
         final Context context = getInstrumentation().getTargetContext();
-        HandlerThread handlerThread = new HandlerThread(TAG);
-        handlerThread.start();
-        Handler handler = new Handler(handlerThread.getLooper());
+        Handler handler = createHandler();
 
         MediaSession session = null;
         try {
@@ -264,9 +270,116 @@
             if (session != null) {
                 session.release();
             }
+            removeHandler(handler);
         }
     }
 
+    public void testGetSession2Tokens() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        Handler handler = createHandler();
+
+        Session2TokenListener listener = new Session2TokenListener();
+        mSessionManager.addOnSession2TokensChangedListener(listener, handler);
+
+        Session2Callback sessionCallback = new Session2Callback();
+        try (MediaSession2 session = new MediaSession2.Builder(context)
+                .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+                .build()) {
+            assertTrue(sessionCallback.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(listener.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            Session2Token currentToken = session.getSessionToken();
+            assertTrue(listContainsToken(listener.mTokens, currentToken));
+            assertTrue(listContainsToken(mSessionManager.getSession2Tokens(), currentToken));
+        }
+    }
+
+    public void testAddAndRemoveSession2TokensListener() throws Exception {
+        final Context context = getInstrumentation().getTargetContext();
+        Handler handler = createHandler();
+
+        Session2TokenListener listener1 = new Session2TokenListener();
+        mSessionManager.addOnSession2TokensChangedListener(listener1, handler);
+
+        Session2Callback sessionCallback = new Session2Callback();
+        try (MediaSession2 session = new MediaSession2.Builder(context)
+                .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+                .build()) {
+            assertTrue(listener1.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            Session2Token currentToken = session.getSessionToken();
+            assertTrue(listContainsToken(listener1.mTokens, currentToken));
+
+            // Test removing listener
+            listener1.resetCountDownLatch();
+            Session2TokenListener listener2 = new Session2TokenListener();
+            mSessionManager.addOnSession2TokensChangedListener(listener2, handler);
+            mSessionManager.removeOnSession2TokensChangedListener(listener1);
+
+            session.close();
+            assertFalse(listener1.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(listener2.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+    }
+
+    public void testNotifySession2Created_withDestroyedToken_shouldThrowIAE() {
+        final Context context = getInstrumentation().getTargetContext();
+
+        MediaSession2 session = new MediaSession2.Builder(context)
+                .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
+                        new Session2Callback())
+                .build();
+        session.close();
+        Session2Token destroyedToken = session.getSessionToken();
+
+        try {
+            mSessionManager.notifySession2Created(destroyedToken);
+            fail("notifySession2Created should throw IAE");
+        } catch (IllegalArgumentException ex) {
+            // Expected.
+        }
+    }
+
+    public void testNotifySession2Destroyed_withLiveToken_shouldThrowIAE() {
+        final Context context = getInstrumentation().getTargetContext();
+
+        MediaSession2 session = new MediaSession2.Builder(context)
+                .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
+                        new Session2Callback())
+                .build();
+        Session2Token liveToken = session.getSessionToken();
+
+        try {
+            mSessionManager.notifySession2Destroyed(liveToken);
+            fail("notifySession2Destroyed should throw IAE");
+        } catch (IllegalArgumentException ex) {
+            // Expected.
+        } finally {
+            session.close();
+        }
+    }
+
+    private boolean listContainsToken(List<Session2Token> tokens, Session2Token token) {
+        for (int i = 0; i < tokens.size(); i++) {
+            if (tokens.get(i).equals(token)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Handler createHandler() {
+        HandlerThread handlerThread = new HandlerThread("MediaSessionManagerTest");
+        handlerThread.start();
+        return new Handler(handlerThread.getLooper());
+    }
+
+    private void removeHandler(Handler handler) {
+        if (handler == null) {
+            return;
+        }
+        handler.getLooper().quitSafely();
+    }
+
     private class VolumeKeyLongPressListener
             implements MediaSessionManager.OnVolumeKeyLongPressListener {
         private final List<KeyEvent> mKeyEvents = new ArrayList<>();
@@ -330,4 +443,39 @@
             return true;
         }
     }
+
+    private class Session2Callback extends MediaSession2.SessionCallback {
+        private CountDownLatch mCountDownLatch;
+
+        private Session2Callback() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        @Override
+        public Session2CommandGroup onConnect(MediaSession2 session,
+                MediaSession2.ControllerInfo controller) {
+            mCountDownLatch.countDown();
+            return new Session2CommandGroup.Builder().build();
+        }
+    }
+
+    private class Session2TokenListener implements
+            MediaSessionManager.OnSession2TokensChangedListener {
+        private CountDownLatch mCountDownLatch;
+        private List<Session2Token> mTokens;
+
+        private Session2TokenListener() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        @Override
+        public void onSession2TokensChanged(List<Session2Token> tokens) {
+            mTokens = tokens;
+            mCountDownLatch.countDown();
+        }
+
+        public void resetCountDownLatch() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
index fe752f8..cc71e1e 100644
--- a/tests/tests/media/src/android/media/cts/MediaSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -36,6 +36,8 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.view.Surface;
@@ -58,6 +60,8 @@
  * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
  * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
  */
+@SmallTest
+@RequiresDevice
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
     private static final String LOG_TAG = "MediaSyncTest";
diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
index 5e4f598..52b6d5d 100644
--- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
@@ -32,6 +32,8 @@
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
 import android.util.Log;
 import android.view.Surface;
 import android.webkit.cts.CtsTestServer;
@@ -65,6 +67,8 @@
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.CharArrayBuffer;
 
+@SmallTest
+@RequiresDevice
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class NativeDecoderTest extends MediaPlayerTestBase {
     private static final String TAG = "DecoderTest";
diff --git a/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
new file mode 100644
index 0000000..cff9f08
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests {@link android.media.Session2CommandGroup}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class Session2CommandGroupTest {
+    private final int TEST_COMMAND_CODE_1 = 10000;
+    private final int TEST_COMMAND_CODE_2 = 10001;
+    private final int TEST_COMMAND_CODE_3 = 10002;
+
+    @Test
+    public void testHasCommand() {
+        Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(TEST_COMMAND_CODE_1);
+        Session2CommandGroup commandGroup = builder.build();
+        assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_1));
+        assertTrue(commandGroup.hasCommand(testCommand));
+        assertFalse(commandGroup.hasCommand(TEST_COMMAND_CODE_2));
+    }
+
+    @Test
+    public void testGetCommands() {
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(TEST_COMMAND_CODE_1);
+        Session2CommandGroup commandGroup = builder.build();
+
+        Set<Session2Command> commands = commandGroup.getCommands();
+        assertTrue(commands.contains(new Session2Command(TEST_COMMAND_CODE_1)));
+        assertFalse(commands.contains(new Session2Command(TEST_COMMAND_CODE_2)));
+    }
+
+    @Test
+    public void testDescribeContents() {
+        final int expected = 0;
+        Session2Command command = new Session2Command(TEST_COMMAND_CODE_1);
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(TEST_COMMAND_CODE_1);
+        Session2CommandGroup commandGroup = builder.build();
+        assertEquals(expected, commandGroup.describeContents());
+    }
+
+    @Test
+    public void testWriteToParcel() {
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(TEST_COMMAND_CODE_1)
+                .addCommand(TEST_COMMAND_CODE_2);
+        Session2CommandGroup commandGroup = builder.build();
+        Parcel dest = Parcel.obtain();
+        commandGroup.writeToParcel(dest, 0);
+        dest.setDataPosition(0);
+        Session2CommandGroup commandGroupFromParcel =
+            Session2CommandGroup.CREATOR.createFromParcel(dest);
+        assertEquals(commandGroup.getCommands(), commandGroupFromParcel.getCommands());
+        dest.recycle();
+    }
+
+    @Test
+    public void testBuilder() {
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(TEST_COMMAND_CODE_1);
+        Session2CommandGroup commandGroup = builder.build();
+        Session2CommandGroup.Builder newBuilder = new Session2CommandGroup.Builder(commandGroup);
+        Session2CommandGroup newCommandGroup = newBuilder.build();
+        assertEquals(commandGroup.getCommands(), newCommandGroup.getCommands());
+    }
+
+    @Test
+    public void testAddAndRemoveCommand() {
+        Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
+        Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+                .addCommand(testCommand)
+                .addCommand(TEST_COMMAND_CODE_2)
+                .addCommand(TEST_COMMAND_CODE_3);
+        builder.removeCommand(testCommand)
+                .removeCommand(TEST_COMMAND_CODE_2);
+        Session2CommandGroup commandGroup = builder.build();
+        assertFalse(commandGroup.hasCommand(testCommand));
+        assertFalse(commandGroup.hasCommand(TEST_COMMAND_CODE_2));
+        assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_3));
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java b/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java
new file mode 100644
index 0000000..c2bd7ef
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import android.media.MediaSession2;
+import android.media.MediaSession2Service;
+import android.media.Session2CommandGroup;
+import android.os.Process;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+
+/**
+ * Stub implementation of {@link MediaSession2Service} for testing.
+ */
+public class StubMediaSession2Service extends MediaSession2Service {
+    /**
+     * ID of the session that this service will create.
+     */
+    private static final String ID = "StubMediaSession2Service";
+
+    @GuardedBy("StubMediaSession2Service.class")
+    private static HandlerExecutor sHandlerExecutor;
+    @GuardedBy("StubMediaSession2Service.class")
+    private static StubMediaSession2Service sInstance;
+    @GuardedBy("StubMediaSession2Service.class")
+    private static TestInjector sTestInjector;
+
+    public static void setHandlerExecutor(HandlerExecutor handlerExecutor) {
+        synchronized (StubMediaSession2Service.class) {
+            sHandlerExecutor = handlerExecutor;
+        }
+    }
+
+    public static StubMediaSession2Service getInstance() {
+        synchronized (StubMediaSession2Service.class) {
+            return sInstance;
+        }
+    }
+
+    public static void setTestInjector(TestInjector injector) {
+        synchronized (StubMediaSession2Service.class) {
+            sTestInjector = injector;
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        synchronized (StubMediaSession2Service.class) {
+            sInstance = this;
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        List<MediaSession2> sessions = getSessions();
+        for (MediaSession2 session : sessions) {
+            session.close();
+        }
+        synchronized (StubMediaSession2Service.class) {
+            if (sTestInjector != null) {
+                sTestInjector.onServiceDestroyed();
+            }
+            sInstance = null;
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public MediaNotification onUpdateNotification(MediaSession2 session) {
+        synchronized (StubMediaSession2Service.class) {
+            if (sTestInjector != null) {
+                sTestInjector.onUpdateNotification(session);
+            }
+            sInstance = null;
+        }
+        return null;
+    }
+
+    @Override
+    public MediaSession2 onGetPrimarySession() {
+        synchronized (StubMediaSession2Service.class) {
+            if (sTestInjector != null) {
+                MediaSession2 session = sTestInjector.onGetPrimarySession();
+                if (session != null) {
+                    return session;
+                }
+            }
+        }
+        if (getSessions().size() > 0) {
+            return getSessions().get(0);
+        }
+        return new MediaSession2.Builder(this)
+                .setId(ID)
+                .setSessionCallback(sHandlerExecutor, new MediaSession2.SessionCallback() {
+                    @Override
+                    public Session2CommandGroup onConnect(MediaSession2 session,
+                            MediaSession2.ControllerInfo controller) {
+                        if (controller.getUid() == Process.myUid()) {
+                            return new Session2CommandGroup.Builder().build();
+                        }
+                        return null;
+                    }
+                }).build();
+    }
+
+    public static abstract class TestInjector {
+        MediaSession2 onGetPrimarySession() {
+            return null;
+        }
+
+        MediaNotification onUpdateNotification(MediaSession2 session) {
+            return null;
+        }
+
+        void onServiceDestroyed() {
+            // no-op
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index ce97379..57ff9d3 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -40,6 +40,7 @@
 import java.util.Arrays;
 import java.util.LinkedList;
 
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class VideoDecoderPerfTest extends MediaPlayerTestBase {
     private static final String TAG = "VideoDecoderPerfTest";
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index 3a2165d..818c95d 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -55,6 +55,7 @@
 import java.util.Map;
 import java.util.Set;
 
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class VideoEncoderTest extends MediaPlayerTestBase {
     private static final int MAX_SAMPLE_SIZE = 256 * 1024;
diff --git a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
index 38a8403..654875f 100644
--- a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
@@ -36,6 +36,7 @@
  * The stream is later decoded by vp8/vp9 decoder to verify frames are decodable and to
  * calculate PSNR values for various bitrates.
  */
+@MediaHeavyPresubmitTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class VpxEncoderTest extends VpxCodecTestBase {
 
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
index d48aeab..4e4d022 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
@@ -130,6 +130,7 @@
     AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
     AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
     AAUDIO_INPUT_PRESET_UNPROCESSED,
+    AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
 };
 
 
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
index 01ed9f6..9bb5484 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
@@ -99,4 +99,5 @@
     static_assert(6 == AAUDIO_INPUT_PRESET_VOICE_RECOGNITION, ENUM_CANNOT_CHANGE);
     static_assert(7 == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION, ENUM_CANNOT_CHANGE);
     static_assert(9 == AAUDIO_INPUT_PRESET_UNPROCESSED, ENUM_CANNOT_CHANGE);
+    static_assert(10 == AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE, ENUM_CANNOT_CHANGE);
 }
diff --git a/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp b/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
index 6ce89a0..2fc9ff8f 100644
--- a/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
+++ b/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
@@ -44,6 +44,10 @@
     revents = wait_fd[0].revents;
     if (revents & POLLIN) {
         int n = android_res_nresult(fd, rcode, buf, bufLen);
+        // Verify that android_res_nresult() closed the fd
+        char dummy;
+        EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
+        EXPECT_EQ(EBADF, errno);
         return n;
     }
 
@@ -78,7 +82,6 @@
     EXPECT_GE(res, 0);
     EXPECT_EQ(rcode, expectedRcode);
 
-
     if (expectedRcode == ns_r_noerror) {
         auto answers = extractIpAddressAnswers(buf, res, ipType);
         EXPECT_GE(answers.size(), 0U);
@@ -101,20 +104,20 @@
 TEST (NativeDnsAsyncTest, Async_Query) {
     // V4
     int fd1 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
     EXPECT_GE(fd1, 0);
     int fd2 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_a, 0);
     EXPECT_GE(fd2, 0);
     expectAnswersValid(fd2, AF_INET, ns_r_noerror);
     expectAnswersValid(fd1, AF_INET, ns_r_noerror);
 
     // V6
     fd1 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_aaaa, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_aaaa, 0);
     EXPECT_GE(fd1, 0);
     fd2 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_aaaa, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_aaaa, 0);
     EXPECT_GE(fd2, 0);
     expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
     expectAnswersValid(fd1, AF_INET6, ns_r_noerror);
@@ -132,9 +135,9 @@
             ns_c_in, ns_t_a, nullptr, 0, nullptr, buf2, sizeof(buf2));
     EXPECT_GT(len2, 0);
 
-    int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, ResNsendFlags(0));
+    int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
     EXPECT_GE(fd1, 0);
-    int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, ResNsendFlags(0));
+    int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
     EXPECT_GE(fd2, 0);
 
     expectAnswersValid(fd2, AF_INET, ns_r_noerror);
@@ -150,9 +153,9 @@
             ns_c_in, ns_t_aaaa, nullptr, 0, nullptr, buf2, sizeof(buf2));
     EXPECT_GT(len2, 0);
 
-    fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, ResNsendFlags(0));
+    fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
     EXPECT_GE(fd1, 0);
-    fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, ResNsendFlags(0));
+    fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
     EXPECT_GE(fd2, 0);
 
     expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
@@ -190,7 +193,7 @@
 
 TEST (NativeDnsAsyncTest, Async_Cancel) {
     int fd = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
     int rcode = -1;
     uint8_t buf[MAXPACKET] = {};
     android_res_cancel(fd);
@@ -204,7 +207,7 @@
     // Empty string to create BLOB and query, we will get empty result and rcode = 0
     // on DNSTLS.
     int fd = android_res_nquery(
-            NETWORK_UNSPECIFIED, "", ns_c_in, ns_t_a, ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, "", ns_c_in, ns_t_a, 0);
     EXPECT_GE(fd, 0);
     expectAnswersValid(fd, AF_INET, ns_r_noerror);
 
@@ -212,44 +215,44 @@
     std::string exceedingDomainQuery = "www." + std::string(255, 'g') + ".com";
 
     fd = android_res_nquery(NETWORK_UNSPECIFIED,
-            exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, ResNsendFlags(0));
+            exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, 0);
     EXPECT_EQ(-EMSGSIZE, fd);
     fd = android_res_nquery(NETWORK_UNSPECIFIED,
-            exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, ResNsendFlags(0));
+            exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, 0);
     EXPECT_EQ(-EMSGSIZE, fd);
 }
 
 TEST (NativeDnsAsyncTest, Async_Send_MALFORMED) {
     uint8_t buf[10] = {};
     // empty BLOB
-    int fd = android_res_nsend(NETWORK_UNSPECIFIED, buf, 10, ResNsendFlags(0));
+    int fd = android_res_nsend(NETWORK_UNSPECIFIED, buf, 10, 0);
     EXPECT_GE(fd, 0);
     expectAnswersNotValid(fd, -EINVAL);
 
     std::vector<uint8_t> largeBuf(2 * MAXPACKET, 0);
     // A buffer larger than 8KB
     fd = android_res_nsend(
-            NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), 0);
     EXPECT_EQ(-EMSGSIZE, fd);
 
     // 1000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of
     // commands to 1024 bytes. TODO: fix this.
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 1000, ResNsendFlags(0));
+    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 1000, 0);
     EXPECT_EQ(-EMSGSIZE, fd);
 
     // 500 bytes filled with 0
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 500, ResNsendFlags(0));
+    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 500, 0);
     EXPECT_GE(fd, 0);
     expectAnswersNotValid(fd, -EINVAL);
 
     // 1000 bytes filled with 0xFF
-    std::vector<uint8_t> ffBuf(1000, 255);
+    std::vector<uint8_t> ffBuf(1000, 0xFF);
     fd = android_res_nsend(
-            NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), ResNsendFlags(0));
+            NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), 0);
     EXPECT_EQ(-EMSGSIZE, fd);
 
     // 500 bytes filled with 0xFF
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, ffBuf.data(), 500, ResNsendFlags(0));
+    fd = android_res_nsend(NETWORK_UNSPECIFIED, ffBuf.data(), 500, 0);
     EXPECT_GE(fd, 0);
     expectAnswersNotValid(fd, -EINVAL);
-}
\ No newline at end of file
+}
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
new file mode 100644
index 0000000..2e40584
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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.net.cts;
+
+import static android.net.DnsResolver.CLASS_IN;
+import static android.net.DnsResolver.TYPE_A;
+import static android.net.DnsResolver.TYPE_AAAA;
+import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DnsResolver;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.system.ErrnoException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DnsResolverTest extends AndroidTestCase {
+    private static final String TAG = "DnsResolverTest";
+    private static final char[] HEX_CHARS = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+    private ConnectivityManager mCM;
+    private Handler mHandler;
+    private DnsResolver mDns;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mHandler = new Handler(Looper.getMainLooper());
+        mDns = DnsResolver.getInstance();
+    }
+
+    private static String bytesArrayToHexString(byte[] bytes) {
+        char[] hexChars = new char[bytes.length * 2];
+        for (int i = 0; i < bytes.length; ++i) {
+            int b = bytes[i] & 0xFF;
+            hexChars[i * 2] = HEX_CHARS[b >>> 4];
+            hexChars[i * 2 + 1] = HEX_CHARS[b & 0x0F];
+        }
+        return new String(hexChars);
+    }
+
+    private Network[] getTestableNetworks() {
+        final ArrayList<Network> testableNetworks = new ArrayList<Network>();
+        for (Network network : mCM.getAllNetworks()) {
+            final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
+            if (nc != null
+                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+                testableNetworks.add(network);
+            }
+        }
+
+        assertTrue(
+                "This test requires that at least one network be connected. " +
+                "Please ensure that the device is connected to a network.",
+                testableNetworks.size() >= 1);
+        return testableNetworks.toArray(new Network[0]);
+    }
+
+    public void testInetAddressQuery() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            CountDownLatch latch = new CountDownLatch(1);
+            final int TIMEOUT_MS = 5_000;
+            final String dname = "www.google.com";
+
+            mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> {
+                    if (answerList.size() != 0) {
+                        latch.countDown();
+                        for (InetAddress addr : answerList) {
+                            Log.e(TAG, "Reported addr:" + addr.toString());
+                        }
+                    }
+                }
+            );
+            String msg = "InetAddress query " + dname + " but no valid answer after "
+                    + TIMEOUT_MS + "ms.";
+            try {
+                assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    public void testRawQuery() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            CountDownLatch latch = new CountDownLatch(1);
+            final int TIMEOUT_MS = 5_000;
+            final String dname = "www.google.com";
+
+            mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> {
+                    if (answer != null) {
+                        latch.countDown();
+                        Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer));
+                    }
+                }
+            );
+            String msg = "Raw query " + dname + " but no valid answer after " + TIMEOUT_MS + "ms.";
+            try {
+                assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    public void testRawQueryWithBlob() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            CountDownLatch latch = new CountDownLatch(1);
+            final int TIMEOUT_MS = 5_000;
+            final byte[] blob = new byte[] {
+                    /* Header */
+                    0x55, 0x66, /* Transaction ID */
+                    0x01, 0x00, /* Flags */
+                    0x00, 0x01, /* Questions */
+                    0x00, 0x00, /* Answer RRs */
+                    0x00, 0x00, /* Authority RRs */
+                    0x00, 0x00, /* Additional RRs */
+                    /* Queries */
+                    0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
+                    0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
+                    0x00, 0x01, /* Type */
+                    0x00, 0x01  /* Class */
+            };
+
+            mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> {
+                    if (answer != null) {
+                        latch.countDown();
+                        Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer));
+                    }
+                }
+            );
+            String msg = "Raw query with blob " + bytesArrayToHexString(blob) +
+                    " but no valid answer after " + TIMEOUT_MS + "ms.";
+            try {
+                assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            } catch (InterruptedException e) {}
+        }
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
index 608475b..77598ed 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -139,6 +139,8 @@
         wifiInfo.getBSSID();
         wifiInfo.getIpAddress();
         wifiInfo.getLinkSpeed();
+        wifiInfo.getTxLinkSpeedMbps();
+        wifiInfo.getRxLinkSpeedMbps();
         wifiInfo.getRssi();
         wifiInfo.getHiddenSSID();
         wifiInfo.getMacAddress();
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 8ea72e0..0337119 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -1023,6 +1023,30 @@
         }
     }
 
+    /**
+     * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE}
+     * permission is held by at most one application.
+     */
+    public void testUpdateWifiUsabilityStatsScorePermission() {
+        final PackageManager pm = getContext().getPackageManager();
+
+        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
+                android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE
+        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
+
+        List<String> uniquePackageNames = holding
+                .stream()
+                .map(pi -> pi.packageName)
+                .distinct()
+                .collect(Collectors.toList());
+
+        if (uniquePackageNames.size() > 1) {
+            fail("The WIFI_UPDATE_USABILITY_STATS_SCORE permission must not be held by more than "
+                + "one application, but is held by " + uniquePackageNames.size() + " applications: "
+                + String.join(", ", uniquePackageNames));
+        }
+    }
+
     private void turnScreenOnNoDelay() throws Exception {
         mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
         mUiDevice.executeShellCommand("wm dismiss-keyguard");
diff --git a/tests/tests/neuralnetworks/Android.mk b/tests/tests/neuralnetworks/Android.mk
index d8b2be2..4b27e7b 100644
--- a/tests/tests/neuralnetworks/Android.mk
+++ b/tests/tests/neuralnetworks/Android.mk
@@ -69,3 +69,5 @@
 LOCAL_NDK_STL_VARIANT := c++_static
 
 include $(BUILD_CTS_EXECUTABLE)
+
+include $(nnapi_cts_dir)/benchmark/Android.mk
diff --git a/tests/tests/neuralnetworks/benchmark/Android.mk b/tests/tests/neuralnetworks/benchmark/Android.mk
new file mode 100644
index 0000000..9670236
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsNNAPIBenchmarkTestCases
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# And when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test androidx.test.rules \
+    compatibility-device-util ctstestrunner junit NeuralNetworksApiBenchmark_Lib
+LOCAL_JNI_SHARED_LIBRARIES := libnnbenchmark_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_ASSET_DIR := test/mlts/models/assets
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml b/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml
new file mode 100644
index 0000000..b2973a9
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.nn.benchmark.cts">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-sdk android:minSdkVersion="27"/>
+
+    <application android:name=".NNAccuracyApplication">
+        <activity android:name=".NNAccuracyActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.nn.benchmark.cts"
+            android:label="CTS tests of NNAPI accuracy benchmark"/>
+</manifest>
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/neuralnetworks/benchmark/AndroidTest.xml
similarity index 69%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/neuralnetworks/benchmark/AndroidTest.xml
index 907fb2d..dd309c7 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/neuralnetworks/benchmark/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -13,16 +13,15 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Configuration for CTS NNAPI Benchmark Tests">
     <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="component" value="neuralnetworks" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+        <option name="test-file-name" value="CtsNNAPIBenchmarkTestCases.apk" />
     </target_preparer>
+
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.libcore.cts.coreplatformapi" />
-        <option name="runtime-hint" value="1m"/>
-        <option name="hidden-api-checks" value="false"/>
+        <option name="package" value="com.android.nn.benchmark.cts" />
     </test>
 </configuration>
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java
new file mode 100644
index 0000000..29877c7
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 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 com.android.nn.benchmark.cts;
+
+import android.app.Activity;
+
+public class NNAccuracyActivity extends Activity {}
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java
new file mode 100644
index 0000000..78e0b1a
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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 com.android.nn.benchmark.cts;
+
+import android.app.Application;
+import com.android.nn.benchmark.core.TestModelsListLoader;
+import java.io.IOException;
+
+/** Application class for NNAccuracyTest. */
+public class NNAccuracyApplication extends Application {
+
+@Override
+  public void onCreate() {
+    super.onCreate();
+    try {
+      TestModelsListLoader.parseFromAssets(getAssets());
+    } catch (IOException e) {
+      throw new IllegalStateException("Failed to load test models json", e);
+    }
+  }
+}
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java
new file mode 100644
index 0000000..be6d40e
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019 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 com.android.nn.benchmark.cts;
+
+import static junit.framework.TestCase.assertFalse;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.test.filters.LargeTest;
+import android.support.test.rule.ActivityTestRule;
+import android.util.Pair;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.nn.benchmark.core.BenchmarkException;
+import com.android.nn.benchmark.core.BenchmarkResult;
+import com.android.nn.benchmark.core.InferenceInOutSequence;
+import com.android.nn.benchmark.core.InferenceResult;
+import com.android.nn.benchmark.core.NNTestBase;
+import com.android.nn.benchmark.core.TestModels;
+import com.android.nn.benchmark.util.TestExternalStorageActivity;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests the accuracy of the model outputs.
+ */
+@RunWith(Parameterized.class)
+public class NNAccuracyTest {
+
+    @Rule
+    public ActivityTestRule<NNAccuracyActivity> mActivityRule =
+            new ActivityTestRule<>(NNAccuracyActivity.class);
+
+    @Parameterized.Parameter(0)
+    public TestModels.TestModelEntry mModel;
+
+    private Activity mActivity;
+
+    // TODO(vddang): Add mobilenet_v1_0.25_128_quant_topk_aosp
+    private static final String[] MODEL_NAMES = new String[]{
+            "tts_float",
+            "asr_float",
+            "mobilenet_v1_1.0_224_quant_topk_aosp",
+            "mobilenet_v1_1.0_224_topk_aosp",
+            "mobilenet_v1_0.75_192_quant_topk_aosp",
+            "mobilenet_v1_0.75_192_topk_aosp",
+            "mobilenet_v1_0.5_160_quant_topk_aosp",
+            "mobilenet_v1_0.5_160_topk_aosp",
+            "mobilenet_v1_0.25_128_topk_aosp",
+            "mobilenet_v2_0.35_128_topk_aosp",
+            "mobilenet_v2_0.5_160_topk_aosp",
+            "mobilenet_v2_0.75_192_topk_aosp",
+            "mobilenet_v2_1.0_224_quant_topk_aosp",
+            "mobilenet_v2_1.0_224_topk_aosp",
+    };
+
+    @Parameters(name = "{0}")
+    public static List<TestModels.TestModelEntry> modelsList() {
+        List<TestModels.TestModelEntry> models = new ArrayList<>();
+        for (String modelName : MODEL_NAMES) {
+            models.add(TestModels.getModelByName(modelName));
+        }
+        return Collections.unmodifiableList(models);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @Test
+    @LargeTest
+    public void testTFLite() throws BenchmarkException, IOException {
+        NNTestBase test = mModel.createNNTestBase(/*useNNAPI=*/false,
+                /*enableIntermediateTensorsDump=*/false);
+        test.setupModel(mActivity);
+        Pair<List<InferenceInOutSequence>, List<InferenceResult>> inferenceResults =
+                test.runBenchmarkCompleteInputSet(/*setRepeat=*/1, /*timeoutSec=*/3600);
+        BenchmarkResult benchmarkResult =
+                BenchmarkResult.fromInferenceResults(
+                        mModel.mModelName,
+                        BenchmarkResult.BACKEND_TFLITE_CPU,
+                        inferenceResults.first,
+                        inferenceResults.second,
+                        test.getEvaluator());
+        assertFalse(benchmarkResult.hasValidationErrors());
+    }
+
+    @Test
+    @LargeTest
+    public void testNNAPI() throws BenchmarkException, IOException {
+        NNTestBase test = mModel.createNNTestBase(/*useNNAPI=*/true,
+                /*enableIntermediateTensorsDump=*/false);
+        test.setupModel(mActivity);
+        Pair<List<InferenceInOutSequence>, List<InferenceResult>> inferenceResults =
+                test.runBenchmarkCompleteInputSet(/*setRepeat=*/1, /*timeoutSec=*/3600);
+        BenchmarkResult benchmarkResult =
+                BenchmarkResult.fromInferenceResults(
+                        mModel.mModelName,
+                        BenchmarkResult.BACKEND_TFLITE_NNAPI,
+                        inferenceResults.first,
+                        inferenceResults.second,
+                        test.getEvaluator());
+        assertFalse(benchmarkResult.hasValidationErrors());
+    }
+}
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml b/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
index 6b52e7a..fb804ef 100644
--- a/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
+++ b/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
@@ -22,6 +22,24 @@
     <application>
         <uses-library android:name="android.test.runner" />
 
+        <service android:name="android.app.notification.legacy29.cts.TestNotificationListener"
+                 android:exported="true"
+                 android:label="TestNotificationListener"
+                 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="android.app.notification.legacy29.cts.TestNotificationAssistant"
+                 android:exported="true"
+                 android:label="TestNotificationAssistant"
+                 android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationAssistantService" />
+            </intent-filter>
+        </service>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
new file mode 100644
index 0000000..2738e01
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2019 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.app.notification.legacy29.cts;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.junit.Assert.assertNotEquals;
+
+import android.app.Instrumentation;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.Telephony;
+import android.service.notification.Adjustment;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationAssistantServiceTest {
+
+    final String TAG = "NotAsstServiceTest";
+    final String NOTIFICATION_CHANNEL_ID = "NotificationAssistantServiceTest";
+    final int ICON_ID = android.R.drawable.sym_def_app_icon;
+    final long SLEEP_TIME = 500; // milliseconds
+
+    private TestNotificationAssistant mNotificationAssistantService;
+    private TestNotificationListener mNotificationListenerService;
+    private NotificationManager mNotificationManager;
+    private Context mContext;
+
+    @Before
+    public void setUp() throws IOException {
+        mContext = InstrumentationRegistry.getContext();
+        toggleAssistantAccess(false);
+        toggleListenerAccess(false);
+
+        mNotificationManager = (NotificationManager) mContext.getSystemService(
+                Context.NOTIFICATION_SERVICE);
+        mNotificationManager.createNotificationChannel(new NotificationChannel(
+                NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        if (mNotificationListenerService != null) mNotificationListenerService.resetData();
+        toggleListenerAccess(false);
+        toggleAssistantAccess(false);
+    }
+
+    @Test
+    public void testOnNotificationEnqueued() throws Exception {
+        toggleListenerAccess(true);
+        Thread.sleep(SLEEP_TIME);
+        mNotificationListenerService = TestNotificationListener.getInstance();
+
+        sendNotification(1, ICON_ID);
+        StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        // No modification because the Notification Assistant is not enabled
+        assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL,
+                out.getUserSentiment());
+        mNotificationListenerService.resetData();
+
+        toggleAssistantAccess(true);
+        Thread.sleep(SLEEP_TIME); // wait for listener and assistant to be allowed
+        mNotificationAssistantService = TestNotificationAssistant.getInstance();
+
+        sendNotification(1, ICON_ID);
+        sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        // Assistant modifies notification
+        assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE,
+                out.getUserSentiment());
+    }
+
+    @Test
+    public void testAdjustNotification_userSentimentKey() throws Exception {
+        setUpListeners();
+
+        sendNotification(1, ICON_ID);
+        StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE,
+                out.getUserSentiment());
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+                NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+        Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+                sbn.getUserId());
+
+        mNotificationAssistantService.adjustNotification(adjustment);
+        Thread.sleep(SLEEP_TIME); // wait for adjustment to be processed
+
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE,
+                out.getUserSentiment());
+    }
+
+    @Test
+    public void testAdjustNotification_importanceKey() throws Exception {
+        setUpListeners();
+
+        sendNotification(1, ICON_ID);
+        StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        int currentImportance = out.getImportance();
+        int newImportance = currentImportance == NotificationManager.IMPORTANCE_DEFAULT
+                ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT;
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_IMPORTANCE, newImportance);
+        Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+                sbn.getUserId());
+
+        mNotificationAssistantService.adjustNotification(adjustment);
+        Thread.sleep(SLEEP_TIME); // wait for adjustment to be processed
+
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        assertEquals(newImportance, out.getImportance());
+    }
+
+    @Test
+    public void testAdjustNotification_smartActionKey() throws Exception {
+        setUpListeners();
+        PendingIntent sendIntent = PendingIntent.getActivity(mContext, 0,
+                new Intent(Intent.ACTION_SEND), 0);
+        Notification.Action sendAction = new Notification.Action.Builder(ICON_ID, "SEND",
+                sendIntent).build();
+
+        sendNotification(1, ICON_ID);
+        StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        List<Notification.Action> smartActions = out.getSmartActions();
+        if (smartActions != null) {
+            for (int i = 0; i < smartActions.size(); i++) {
+                Notification.Action action = smartActions.get(i);
+                assertNotEquals(sendIntent, action.actionIntent);
+            }
+        }
+
+        ArrayList<Notification.Action> extraAction = new ArrayList<>();
+        extraAction.add(sendAction);
+        Bundle signals = new Bundle();
+        signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, extraAction);
+        Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+                sbn.getUserId());
+
+        mNotificationAssistantService.adjustNotification(adjustment);
+        Thread.sleep(SLEEP_TIME); //wait for adjustment to be processed
+
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        boolean actionFound = false;
+        smartActions = out.getSmartActions();
+        for (int i = 0; i < smartActions.size(); i++) {
+            Notification.Action action = smartActions.get(i);
+            actionFound = actionFound || action.actionIntent.equals(sendIntent);
+        }
+        assertTrue(actionFound);
+    }
+
+    @Test
+    public void testAdjustNotification_smartReplyKey() throws Exception {
+        setUpListeners();
+        CharSequence smartReply = "Smart Reply!";
+
+        sendNotification(1, ICON_ID);
+        StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+        NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        List<CharSequence> smartReplies = out.getSmartReplies();
+        if (smartReplies != null) {
+            for (int i = 0; i < smartReplies.size(); i++) {
+                CharSequence reply = smartReplies.get(i);
+                assertNotEquals(smartReply, reply);
+            }
+        }
+
+        ArrayList<CharSequence> extraReply = new ArrayList<>();
+        extraReply.add(smartReply);
+        Bundle signals = new Bundle();
+        signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, extraReply);
+        Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+                sbn.getUserId());
+
+        mNotificationAssistantService.adjustNotification(adjustment);
+        Thread.sleep(SLEEP_TIME); //wait for adjustment to be processed
+
+        mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+        boolean replyFound = false;
+        smartReplies = out.getSmartReplies();
+        for (int i = 0; i < smartReplies.size(); i++) {
+            CharSequence reply = smartReplies.get(i);
+            replyFound = replyFound || reply.equals(smartReply);
+        }
+        assertTrue(replyFound);
+    }
+
+    private StatusBarNotification getFirstNotificationFromPackage(String PKG)
+            throws InterruptedException {
+        StatusBarNotification sbn = mNotificationListenerService.mPosted.poll(SLEEP_TIME,
+                TimeUnit.MILLISECONDS);
+        assertNotNull(sbn);
+        while (!sbn.getPackageName().equals(PKG)) {
+            sbn = mNotificationListenerService.mPosted.poll(SLEEP_TIME, TimeUnit.MILLISECONDS);
+        }
+        assertNotNull(sbn);
+        return sbn;
+    }
+
+    private void setUpListeners() throws Exception {
+        toggleListenerAccess(true);
+        toggleAssistantAccess(true);
+        Thread.sleep(2 * SLEEP_TIME); // wait for listener and assistant to be allowed
+
+        mNotificationListenerService = TestNotificationListener.getInstance();
+        mNotificationAssistantService = TestNotificationAssistant.getInstance();
+
+        assertNotNull(mNotificationListenerService);
+        assertNotNull(mNotificationAssistantService);
+    }
+
+    private void sendNotification(final int id, final int icon) throws Exception {
+        sendNotification(id, null, icon);
+    }
+
+    private void sendNotification(final int id, String groupKey, final int icon) throws Exception {
+        final Intent intent = new Intent(Intent.ACTION_MAIN, Telephony.Threads.CONTENT_URI);
+
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        intent.setAction(Intent.ACTION_MAIN);
+
+        final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+        final Notification notification =
+                new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+                        .setSmallIcon(icon)
+                        .setWhen(System.currentTimeMillis())
+                        .setContentTitle("notify#" + id)
+                        .setContentText("This is #" + id + "notification  ")
+                        .setContentIntent(pendingIntent)
+                        .setGroup(groupKey)
+                        .build();
+        mNotificationManager.notify(id, notification);
+    }
+
+    private void toggleListenerAccess(boolean on) throws IOException {
+
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        String componentName = TestNotificationListener.getId();
+
+        String command = " cmd notification " + (on ? "allow_listener " : "disallow_listener ")
+                + componentName;
+
+        runCommand(command, instrumentation);
+
+        final ComponentName listenerComponent = TestNotificationListener.getComponentName();
+        final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
+        Assert.assertTrue(listenerComponent + " has not been " + (on ? "allowed" : "disallowed"),
+                nm.isNotificationListenerAccessGranted(listenerComponent) == on);
+    }
+
+    private void toggleAssistantAccess(boolean on) throws IOException {
+
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        String componentName = TestNotificationAssistant.getId();
+
+        String command = " cmd notification " + (on ? "allow_assistant " : "disallow_assistant ")
+                + componentName;
+
+        runCommand(command, instrumentation);
+
+        final ComponentName assistantComponent = TestNotificationAssistant.getComponentName();
+        final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
+        assertTrue(assistantComponent + " has not been " + (on ? "allowed" : "disallowed"),
+                nm.isNotificationAssistantAccessGranted(assistantComponent) == on);
+    }
+
+    private void runCommand(String command, Instrumentation instrumentation) throws IOException {
+        UiAutomation uiAutomation = instrumentation.getUiAutomation();
+        // Execute command
+        try (ParcelFileDescriptor fd = uiAutomation.executeShellCommand(command)) {
+            assertNotNull("Failed to execute shell command: " + command, fd);
+            // Wait for the command to finish by reading until EOF
+            try (InputStream in = new FileInputStream(fd.getFileDescriptor())) {
+                byte[] buffer = new byte[4096];
+                while (in.read(buffer) > 0) {
+                }
+            } catch (IOException e) {
+                throw new IOException("Could not read stdout of command: " + command, e);
+            }
+        } finally {
+            uiAutomation.destroy();
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java
new file mode 100644
index 0000000..745046d
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 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.app.notification.legacy29.cts;
+
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.service.notification.Adjustment;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+
+public class TestNotificationAssistant extends NotificationAssistantService {
+    public static final String TAG = "TestNotificationAssistant";
+    public static final String PKG = "android.app.notification.legacy29.cts";
+
+    private static TestNotificationAssistant sNotificationAssistantInstance = null;
+    boolean isConnected;
+
+    public static String getId() {
+        return String.format("%s/%s", TestNotificationAssistant.class.getPackage().getName(),
+                TestNotificationAssistant.class.getName());
+    }
+
+    public static ComponentName getComponentName() {
+        return new ComponentName(TestNotificationAssistant.class.getPackage().getName(),
+                TestNotificationAssistant.class.getName());
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onListenerConnected() {
+        super.onListenerConnected();
+        sNotificationAssistantInstance = this;
+        isConnected = true;
+    }
+
+    @Override
+    public void onListenerDisconnected() {
+        isConnected = false;
+    }
+
+    public static TestNotificationAssistant getInstance() {
+        return sNotificationAssistantInstance;
+    }
+
+    public void onNotificationSnoozedUntilContext(StatusBarNotification statusBarNotification,
+            String s) {
+    }
+
+    @Override
+    public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_USER_SENTIMENT, Ranking.USER_SENTIMENT_POSITIVE);
+        return new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+                sbn.getUserId());
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java
new file mode 100644
index 0000000..aea3914
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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.app.notification.legacy29.cts;
+
+import android.content.ComponentName;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import java.util.ArrayList;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+public class TestNotificationListener extends NotificationListenerService {
+    public static final String TAG = "TestNotificationListener";
+    public static final String PKG = "android.app.notification.legacy29.cts";
+
+    private ArrayList<String> mTestPackages = new ArrayList<>();
+
+    public BlockingQueue<StatusBarNotification> mPosted = new ArrayBlockingQueue<>(10);
+    public ArrayList<StatusBarNotification> mRemoved = new ArrayList<>();
+    public RankingMap mRankingMap;
+
+    private static TestNotificationListener
+            sNotificationListenerInstance = null;
+    boolean isConnected;
+
+    public static String getId() {
+        return String.format("%s/%s", TestNotificationListener.class.getPackage().getName(),
+                TestNotificationListener.class.getName());
+    }
+
+    public static ComponentName getComponentName() {
+        return new ComponentName(TestNotificationListener.class.getPackage().getName(),
+                TestNotificationListener.class.getName());
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mTestPackages.add(PKG);
+    }
+
+    @Override
+    public void onListenerConnected() {
+        super.onListenerConnected();
+        sNotificationListenerInstance = this;
+        isConnected = true;
+    }
+
+    @Override
+    public void onListenerDisconnected() {
+        isConnected = false;
+    }
+
+    public static TestNotificationListener getInstance() {
+        return sNotificationListenerInstance;
+    }
+
+    public void resetData() {
+        mPosted.clear();
+        mRemoved.clear();
+    }
+
+    @Override
+    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+        if (!PKG.equals(sbn.getPackageName())) {
+            return;
+        }
+        mRankingMap = rankingMap;
+        mPosted.add(sbn);
+    }
+
+    @Override
+    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+        if (!mTestPackages.contains(sbn.getPackageName())) {
+            return;
+        }
+        mRankingMap = rankingMap;
+        mRemoved.add(sbn);
+    }
+
+    @Override
+    public void onNotificationRankingUpdate(RankingMap rankingMap) {
+        mRankingMap = rankingMap;
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java b/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
index 5a2512d..322d60b 100644
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
@@ -298,6 +298,63 @@
         }
     }
 
+    @CddTest(requirement="7.1.4.5/C-1-4")
+    @Test
+    public void testRequiredGLESVersion() {
+        // This requirement only applies if device claims to be wide color capable.
+        boolean isWideColorCapable =
+            mActivity.getResources().getConfiguration().isScreenWideColorGamut();
+        if (!isWideColorCapable)
+            return;
+
+        int reportedVersion = getVersionFromActivityManager(mActivity);
+        assertEquals("Reported OpenGL ES major version doesn't meet the requirement of" +
+            " CDD 7.1.4.5/C-1-4", 3, getMajorVersion(reportedVersion));
+        assertTrue("Reported OpenGL ES minor version doesn't meet the requirement of" +
+            " CDD 7.1.4.5/C-1-4", 1 == getMinorVersion(reportedVersion) ||
+                                  2 == getMinorVersion(reportedVersion));
+    }
+
+    @CddTest(requirement="7.1.4.5/C-1-5")
+    @Test
+    public void testRequiredEglExtensionsForWideColorDisplay() {
+        // See CDD section 7.1.4.5
+        // This test covers the EGL portion of the CDD requirement. The VK portion of the
+        // requirement is covered elsewhere.
+        final String requiredEglList[] = {
+            "EGL_KHR_no_config_context",
+            "EGL_EXT_pixel_format_float",
+            "EGL_KHR_gl_colorspace",
+            "EGL_EXT_gl_colorspace_scrgb",
+            "EGL_EXT_gl_colorspace_scrgb_linear",
+            "EGL_EXT_gl_colorspace_display_p3",
+            "EGL_EXT_gl_colorspace_display_p3_linear",
+            "EGL_EXT_gl_colorspace_display_p3_passthrough",
+        };
+
+        // This requirement only applies if device claims to be wide color capable.
+        boolean isWideColorCapable = mActivity.getResources().getConfiguration().isScreenWideColorGamut();
+        if (!isWideColorCapable)
+            return;
+
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+        if (egl.eglInitialize(display, null)) {
+            try {
+                String eglExtensions = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);
+                for (int i = 0; i < requiredEglList.length; ++i) {
+                    assertTrue("EGL extension required by CDD section 7.1.4.5 missing: " +
+                        requiredEglList[i], hasExtension(eglExtensions, requiredEglList[i]));
+                }
+            } finally {
+                egl.eglTerminate(display);
+            }
+        } else {
+            Log.e(TAG, "Couldn't initialize EGL.");
+        }
+    }
+
     private boolean isHandheld() {
         // handheld nature is not exposed to package manager, for now
         // we check for touchscreen and NOT watch and NOT tv
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 1fb4056..a524005 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_MULTILIB := both
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hidl.manager-V1.0-java \
     android-support-test \
     compatibility-device-util \
     ctstestrunner \
diff --git a/tests/tests/os/src/android/os/cts/HwBinderTest.java b/tests/tests/os/src/android/os/cts/HwBinderTest.java
new file mode 100644
index 0000000..d3ebe70
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/HwBinderTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2019 Google Inc.
+ *
+ * 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.os.cts;
+
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.HwBlob;
+import android.os.RemoteException;
+
+import junit.framework.TestCase;
+
+import java.util.Calendar;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Unit tests for HwBinder.
+ *
+ * If you want to create a real hwbinder service, using hidl-gen will be
+ * *much* *much* easier. Using something like this is strongly not recommended
+ * because you can't take advantage of the versioning tools, the C++ and Java
+ * interoperability, etc..
+ */
+public class HwBinderTest extends TestCase {
+
+    private static class MarshalCase {
+        interface DoMarshalCase {
+            void test(HwBlob blob, int offset);
+        }
+
+        MarshalCase(String name, int size, DoMarshalCase method) {
+            mName = name;
+            mSize = size;
+            mMethod = method;
+        }
+
+        private String mName;
+        private int mSize;
+        private DoMarshalCase mMethod;
+
+        public String getName() {
+            return mName;
+        }
+
+        void test(int deltaSize, int offset) {
+            HwBlob blob = new HwBlob(mSize + deltaSize);
+            mMethod.test(blob, offset);
+        }
+    }
+
+    private static final MarshalCase[] sMarshalCases = {
+        new MarshalCase("Bool", 1, (blob, offset) -> {
+            blob.putBool(offset, true);
+            assertEquals(true, blob.getBool(offset));
+        }),
+        new MarshalCase("Int8", 1, (blob, offset) -> {
+            blob.putInt8(offset, (byte) 3);
+            assertEquals((byte) 3, blob.getInt8(offset));
+        }),
+        new MarshalCase("Int16", 2, (blob, offset) -> {
+            blob.putInt16(offset, (short) 3);
+            assertEquals((short) 3, blob.getInt16(offset));
+        }),
+        new MarshalCase("Int32", 4, (blob, offset) -> {
+            blob.putInt32(offset, 3);
+            assertEquals(3, blob.getInt32(offset));
+        }),
+        new MarshalCase("Int64", 8, (blob, offset) -> {
+            blob.putInt64(offset, 3);
+            assertEquals(3, blob.getInt64(offset));
+        }),
+        new MarshalCase("Float", 4, (blob, offset) -> {
+            blob.putFloat(offset, 3.0f);
+            assertEquals(3.0f, blob.getFloat(offset));
+        }),
+        new MarshalCase("Double", 8, (blob, offset) -> {
+            blob.putDouble(offset, 3.0);
+            assertEquals(3.0, blob.getDouble(offset));
+        }),
+        new MarshalCase("String", 16, (blob, offset) -> {
+            blob.putString(offset, "foo");
+            assertEquals("foo", blob.getString(offset));
+        }),
+        new MarshalCase("BoolArray", 2, (blob, offset) -> {
+            blob.putBoolArray(offset, new boolean[]{true, false});
+            assertEquals(true, blob.getBool(offset));
+            assertEquals(false, blob.getBool(offset + 1));
+        }),
+        new MarshalCase("Int8Array", 2, (blob, offset) -> {
+            blob.putInt8Array(offset, new byte[]{(byte) 3, (byte) 2});
+            assertEquals((byte) 3, blob.getInt8(offset));
+            assertEquals((byte) 2, blob.getInt8(offset + 1));
+        }),
+        new MarshalCase("Int16Array", 4, (blob, offset) -> {
+            blob.putInt16Array(offset, new short[]{(short) 3, (short) 2});
+            assertEquals((short) 3, blob.getInt16(offset));
+            assertEquals((short) 2, blob.getInt16(offset + 2));
+        }),
+        new MarshalCase("Int32Array", 8, (blob, offset) -> {
+            blob.putInt32Array(offset, new int[]{3, 2});
+            assertEquals(3, blob.getInt32(offset));
+            assertEquals(2, blob.getInt32(offset + 4));
+        }),
+        new MarshalCase("Int64Array", 16, (blob, offset) -> {
+            blob.putInt64Array(offset, new long[]{3, 2});
+            assertEquals(3, blob.getInt64(offset));
+            assertEquals(2, blob.getInt64(offset + 8));
+        }),
+        new MarshalCase("FloatArray", 8, (blob, offset) -> {
+            blob.putFloatArray(offset, new float[]{3.0f, 2.0f});
+            assertEquals(3.0f, blob.getFloat(offset));
+            assertEquals(2.0f, blob.getFloat(offset + 4));
+        }),
+        new MarshalCase("DoubleArray", 16, (blob, offset) -> {
+            blob.putDoubleArray(offset, new double[]{3.0, 2.0});
+            assertEquals(3.0, blob.getDouble(offset));
+            assertEquals(2.0, blob.getDouble(offset + 8));
+        }),
+    };
+
+    public void testAccurateMarshall() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            marshalCase.test(0 /* deltaSize */, 0 /* offset */);
+        }
+    }
+    public void testAccurateMarshallWithExtraSpace() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            marshalCase.test(1 /* deltaSize */, 0 /* offset */);
+        }
+    }
+    public void testAccurateMarshallWithExtraSpaceAndOffset() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            marshalCase.test(1 /* deltaSize */, 1 /* offset */);
+        }
+    }
+    public void testNotEnoughSpaceBecauseOfSize() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            try {
+                marshalCase.test(-1 /* deltaSize */, 0 /* offset */);
+                fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+            } catch (IndexOutOfBoundsException e) {
+                // we expect to see this
+            }
+        }
+    }
+    public void testNotEnoughSpaceBecauseOfOffset() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            try {
+                marshalCase.test(0 /* deltaSize */, 1 /* offset */);
+                fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+            } catch (IndexOutOfBoundsException e) {
+                // we expect to see this
+            }
+        }
+    }
+    public void testNotEnoughSpaceBecauseOfSizeAndOffset() {
+        for (MarshalCase marshalCase : sMarshalCases) {
+            try {
+                marshalCase.test(-1 /* deltaSize */, 1 /* offset */);
+                fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+            } catch (IndexOutOfBoundsException e) {
+                // we expect to see this
+            }
+        }
+    }
+
+    private static class ServiceNotification extends IServiceNotification.Stub {
+        public Lock lock = new ReentrantLock();
+        public Condition condition = lock.newCondition();
+        public boolean registered = false;
+
+        @Override
+        public void onRegistration(String fqName, String name, boolean preexisting) {
+            registered = true;
+            condition.signal();
+        }
+    }
+
+    public void testHwBinder() throws RemoteException {
+        ServiceNotification notification = new ServiceNotification();
+
+        IServiceManager manager = IServiceManager.getService();
+        manager.registerForNotifications(IServiceManager.kInterfaceName, "default", notification);
+
+        Calendar deadline = Calendar.getInstance();
+        deadline.add(Calendar.SECOND, 10);
+
+        notification.lock.lock();
+        try {
+            while (!notification.registered && Calendar.getInstance().before(deadline)) {
+                try {
+                    notification.condition.awaitUntil(deadline.getTime());
+                } catch (InterruptedException e) {
+
+                }
+            }
+        } finally {
+            notification.lock.unlock();
+        }
+
+        assertTrue(notification.registered);
+    }
+}
diff --git a/tests/tests/permission/AndroidManifest.xml b/tests/tests/permission/AndroidManifest.xml
index 0de5496..928da95 100644
--- a/tests/tests/permission/AndroidManifest.xml
+++ b/tests/tests/permission/AndroidManifest.xml
@@ -36,8 +36,8 @@
     <permission android:name="android.permission.cts.D"
                 android:usageInfoRequired="true" />
 
-    <!-- for android.permission.cts.PermissionUsage -->
-    <uses-permission android:name="android.permission.READ_CONTACTS"
+    <!-- for android.permission.cts.PermissionUsage and LocationAccessCheckTest -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
       android:dataSentOffDevice="no"
       android:dataSharedWithThirdParty="no"
       android:dataUsedForMonetization="no"
@@ -60,9 +60,6 @@
     <!-- for android.permission.cts.PermissionUsage -->
     <uses-permission android:name="android.permission.READ_CALENDAR" />
 
-    <!-- for android.permission.cts.LocationAccessCheckTest -->
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
     <!-- for android.permission.cts.PermissionGroupChange -->
     <permission-group android:description="@string/perm_group_b"
                       android:label="@string/perm_group_b"
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 5203705..7661585d 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -1040,6 +1040,21 @@
     }
 
     @Test
+    public void testProcUUIDReadable() throws Exception {
+        File f = new File("/proc/sys/kernel/random/uuid");
+
+        assertTrue(f + " cannot be opened for reading", canOpenForReading(f));
+        assertFalse(f + " can be opened for writing", canOpenForWriting(f));
+
+        FileUtils.FileStatus status = new FileUtils.FileStatus();
+        assertTrue(FileUtils.getFileStatus(f.getPath(), status, false));
+        assertTrue(
+                f + " not 0444. Actual mode: 0"
+                        + Integer.toString(status.mode, 8),
+                (status.mode & 0666) == 0444);
+    }
+
+    @Test
     public void testDevHwRandomLockedDown() throws Exception {
         File f = new File("/dev/hw_random");
         if (!f.exists()) {
diff --git a/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java b/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
index 5752801..39c66a6 100644
--- a/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
@@ -54,7 +54,7 @@
     }
 
     public void testBasic() throws Exception {
-        UsesPermissionInfo upi = getUsesPermissionInfo(Manifest.permission.READ_CONTACTS);
+        UsesPermissionInfo upi = getUsesPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION);
         assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataSentOffDevice());
         assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataSharedWithThirdParty());
         assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataUsedForMonetization());
diff --git a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
index b8f587a..b203f14 100644
--- a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
@@ -16,7 +16,7 @@
 
 package android.permission.cts;
 
-import static com.google.common.truth.Truth.assertThat;
+import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
 
 import android.content.ContentValues;
 import android.content.Intent;
@@ -29,6 +29,7 @@
 import android.provider.CallLog;
 import android.provider.Contacts;
 import android.provider.ContactsContract;
+import android.provider.MediaStore;
 import android.provider.Settings;
 import android.provider.Telephony;
 import android.test.AndroidTestCase;
@@ -217,18 +218,34 @@
     }
 
     /**
-     * Verify that the holder of the MANAGE_DOCUMENTS permission is com.android.documentsui.
+     * The {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission is
+     * a very powerful permission that grants raw storage access to all devices,
+     * and as such it's only appropriate to be granted to the media stack. Any
+     * apps with a user-visible component (such as Camera or Gallery apps) must
+     * go through public {@link MediaStore} APIs, to ensure that users have
+     * meaningful permission controls.
+     * <p>
+     * For example, if the end user revokes the "Music" permission from an app,
+     * but that app still has raw access to music via
+     * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}, that would be a
+     * privacy incident.
      */
-    public void testManageDocumentsMustIncludedInDocumentUi() {
+    public void testMediaStackPermissions() throws Exception {
+        // The only apps holding this permission should be the internal media
+        // stack, and the best way to identify them is having no launchable UI.
         final PackageManager pm = getContext().getPackageManager();
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.MANAGE_DOCUMENTS
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
-        assertThat(holding.size()).isAtMost(1);
-        if (holding.size() == 1) {
-            assertThat(holding.get(0).packageName).isEqualTo("com.android.documentsui");
+        final List<PackageInfo> pkgs = pm
+                .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES);
+        for (PackageInfo pkg : pkgs) {
+            final boolean isSystem = pkg.applicationInfo.uid == android.os.Process.SYSTEM_UID;
+            final boolean hasFrontDoor = pm.getLaunchIntentForPackage(pkg.packageName) != null;
+            final boolean hasPermission = pm.checkPermission(WRITE_MEDIA_STORAGE,
+                    pkg.packageName) == PackageManager.PERMISSION_GRANTED;
+            if (!isSystem && hasFrontDoor && hasPermission) {
+                fail("Found " + pkg.packageName + " holding WRITE_MEDIA_STORAGE permission while "
+                        + "also having user-visible UI; this permission must only be held by "
+                        + "the core media stack, and must not be granted to user-launchable apps");
+            }
         }
     }
 }
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 380407c..3b367fc 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1622,6 +1622,12 @@
     <permission android:name="android.permission.WIFI_SET_DEVICE_MOBILITY_STATE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- #SystemApi @hide Allows privileged system APK to update Wifi usability stats and score.
+         <p>Not for use by third-party applications. This should only be used by a privileged app.
+    -->
+    <permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_LOWPAN_STATE"
@@ -2212,8 +2218,9 @@
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
         android:protectionLevel="signature|installer" />
 
-    <!-- @SystemApi Allows an application to start an activity within its managed profile from
-         the personal profile.
+    <!-- @SystemApi Allows an application to start its own activities, but on a different profile
+         associated with the user. For example, an application running on the main profile of a user
+         can start an activity on a managed profile of that user.
          This permission is not available to third party applications.
          @hide -->
     <permission android:name="android.permission.INTERACT_ACROSS_PROFILES"
@@ -2272,6 +2279,11 @@
     <permission android:name="android.permission.START_ANY_ACTIVITY"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to start activities from background
+         @hide -->
+    <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
+        android:protectionLevel="signature|privileged|vendorPrivileged|oem" />
+
     <!-- @SystemApi Must be required by activities that handle the intent action
          {@link Intent#ACTION_SEND_SHOW_SUSPENDED_APP_DETAILS}. This is for use by apps that
          hold {@link Manifest.permission#SUSPEND_APPS} to interact with the system.
@@ -2530,6 +2542,16 @@
     <permission android:name="android.permission.WRITE_GSERVICES"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi @hide Allows an application to modify config settings.
+    <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.WRITE_DEVICE_CONFIG"
+        android:protectionLevel="signature|configurator"/>
+
+    <!-- @SystemApi @hide Allows an application to read config settings.
+    <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.READ_DEVICE_CONFIG"
+        android:protectionLevel="signature|preinstalled" />
+
     <!-- @SystemApi @TestApi Allows an application to call
         {@link android.app.ActivityManager#forceStopPackage}.
         @hide -->
@@ -3048,6 +3070,14 @@
     <permission android:name="android.permission.BIND_TEXT_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Must be required by a AttentionService
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature
+         @hide
+    -->
+    <permission android:name="android.permission.BIND_ATTENTION_SERVICE"
+                android:protectionLevel="signature" />
+
     <!-- Must be required by a {@link android.net.VpnService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
@@ -3199,9 +3229,10 @@
 
     <!-- @SystemApi Required to add or remove another application as a device admin.
          <p>Not for use by third-party applications.
-         @hide -->
+         @hide
+         @removed -->
     <permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an app to reset the device password.
          <p>Not for use by third-party applications.
@@ -3523,19 +3554,25 @@
     <permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows an application to provide remote displays.
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.REMOTE_DISPLAY_PROVIDER"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows an application to capture video output.
          <p>Not for use by third-party applications.</p>
           @hide
           @removed -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to capture secure video output.
          <p>Not for use by third-party applications.</p>
           @hide
           @removed -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
@@ -3870,7 +3907,7 @@
 
     <!-- @SystemApi @hide Allows managing apk level rollbacks. -->
     <permission android:name="android.permission.MANAGE_ROLLBACKS"
-        android:protectionLevel="signature|installer" />
+        android:protectionLevel="signature|verifier" />
 
     <!-- @SystemApi @hide Allows an application to mark other applications as harmful -->
     <permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS"
@@ -4395,6 +4432,11 @@
     <permission android:name="android.permission.AMBIENT_WALLPAPER"
                 android:protectionLevel="signature|preinstalled" />
 
+    <!-- Allows the device to be reset, clearing all data and enables Test Harness Mode.
+         @hide-->
+    <permission android:name="android.permission.ENABLE_TEST_HARNESS_MODE"
+        android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
similarity index 95%
rename from tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
rename to tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
index df69c94..d1d42bc 100644
--- a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.permission.cts;
+package android.permission2.cts;
 
 import android.app.PendingIntent;
 import android.content.Context;
@@ -374,24 +374,6 @@
     }
 
     /**
-     * Verify that checking clearTestProviderLocation for network requires
-     * permissions.
-     * <p>
-     * Requires Permission:
-     * {@link android.Manifest.permission#ACCESS_MOCK_LOCATION}.
-     */
-    @SmallTest
-    public void testClearTestProviderLocation() {
-        try {
-            mLocationManager.clearTestProviderLocation(TEST_PROVIDER_NAME);
-            fail("LocationManager.clearTestProviderLocation did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    /**
      * Verify that checking setTestProviderEnabled requires permissions.
      * <p>
      * Requires Permission:
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 6916f83..b0ba8fa 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -303,6 +303,9 @@
                 case "privileged": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_PRIVILEGED;
                 } break;
+                case "oem": {
+                    protectionLevel |= PermissionInfo.PROTECTION_FLAG_OEM;
+                } break;
                 case "vendorPrivileged": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED;
                 } break;
@@ -315,6 +318,9 @@
                 case "wellbeing": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_WELLBEING;
                 } break;
+                case "configurator": {
+                    protectionLevel |= PermissionInfo.PROTECTION_FLAG_CONFIGURATOR;
+                } break;
                 case "documenter": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_DOCUMENTER;
                 } break;
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
new file mode 100644
index 0000000..1079cf8
--- /dev/null
+++ b/tests/tests/provider/Android.bp
@@ -0,0 +1,37 @@
+
+android_test {
+    name: "CtsProviderTestCases",
+    defaults: ["cts_defaults"],
+
+    compile_multilib: "both",
+
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+
+    libs: [
+        "android.test.mock",
+        "android.test.base.stubs",
+        "android.test.runner.stubs",
+        "telephony-common",
+    ],
+
+    static_libs: [
+        "compatibility-device-util",
+        "ctstestrunner",
+        "junit",
+        "truth-prebuilt",
+    ],
+
+    jni_libs: [
+        "libcts_jni",
+        "libnativehelper_compat_libc++",
+    ],
+
+    srcs: ["src/**/*.java"],
+
+    sdk_version: "test_current",
+    min_sdk_version: "21",
+}
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index e7def77..6361f9b 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -1,50 +1,2 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-# Include both the 32 and 64 bit versions of libs
-LOCAL_MULTILIB := both
-
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-LOCAL_JAVA_LIBRARIES := android.test.mock android.test.base.stubs android.test.runner.stubs telephony-common
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    compatibility-device-util \
-    ctstestrunner \
-    junit \
-    truth-prebuilt
-
-LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativehelper_compat_libc++
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsProviderTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MIN_SDK_VERSION := 21
-
-include $(BUILD_CTS_PACKAGE)
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml
index bca4189..cafbdaa 100644
--- a/tests/tests/provider/AndroidTest.xml
+++ b/tests/tests/provider/AndroidTest.xml
@@ -17,6 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <target_preparer class="android.provider.cts.preconditions.ExternalStoragePreparer" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsProviderTestCases.apk" />
diff --git a/tests/tests/provider/preconditions/Android.mk b/tests/tests/provider/preconditions/Android.mk
new file mode 100644
index 0000000..f4063c4
--- /dev/null
+++ b/tests/tests/provider/preconditions/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-host-provider-preconditions
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java b/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java
new file mode 100644
index 0000000..5007cea
--- /dev/null
+++ b/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.provider.cts.preconditions;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * Creates secondary external storage for use during a test suite.
+ */
+public class ExternalStoragePreparer implements ITargetPreparer, ITargetCleaner {
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException {
+        if (!hasIsolatedStorage(device)) return;
+
+        device.executeShellCommand("sm set-virtual-disk false");
+        device.executeShellCommand("sm set-virtual-disk true");
+
+        // Partition disks to make sure they're usable by tests
+        final String diskId = getVirtualDisk(device);
+        device.executeShellCommand("sm partition " + diskId + " public");
+    }
+
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable throwable)
+            throws DeviceNotAvailableException {
+        if (!hasIsolatedStorage(device)) return;
+
+        device.executeShellCommand("sm set-virtual-disk false");
+    }
+
+    private boolean hasIsolatedStorage(ITestDevice device) throws DeviceNotAvailableException {
+        return device.executeShellCommand("getprop sys.isolated_storage_snapshot")
+                .contains("true");
+    }
+
+    private String getVirtualDisk(ITestDevice device) throws DeviceNotAvailableException {
+        int attempt = 0;
+        String disks = device.executeShellCommand("sm list-disks");
+        while ((disks == null || disks.isEmpty()) && attempt++ < 15) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ignored) {
+            }
+            disks = device.executeShellCommand("sm list-disks");
+        }
+
+        if (disks == null || disks.isEmpty()) {
+            throw new AssertionError("Device must support virtual disk to verify behavior");
+        }
+        return disks.split("\n")[0].trim();
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
index 1fabb4e..cb8eeda 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
@@ -22,7 +22,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.provider.BlockedNumberContract;
-import android.telecom.Log;
+import android.util.Log;
 
 /**
  * CTS tests for backup and restore of blocked numbers using local transport.
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
index 30fdf24..39aa0bb 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -16,7 +16,6 @@
 
 package android.provider.cts;
 
-import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -323,7 +322,7 @@
     }
 
     private Uri assertInsertBlockedNumberSucceeds(
-            String originalNumber, @Nullable String e164Number) {
+            String originalNumber, String e164Number) {
         ContentValues cv = new ContentValues();
         cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
         if (e164Number != null) {
diff --git a/tests/tests/provider/src/android/provider/cts/FontsContractTest.java b/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
index ea88369..631401a 100644
--- a/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
@@ -40,8 +40,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.internal.annotations.GuardedBy;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -99,13 +97,13 @@
 
     private static class TestCallback extends FontsContract.FontRequestCallback {
         private final Object mLock = new Object();
-        @GuardedBy("mLock")
+        // @GuardedBy("mLock")
         private Typeface mTypeface;
-        @GuardedBy("mLock")
+        // @GuardedBy("mLock")
         private int mFailedReason;
-        @GuardedBy("mLock")
+        // @GuardedBy("mLock")
         private int mSuccessCallCount;
-        @GuardedBy("mLock")
+        // @GuardedBy("mLock")
         private int mFailedCallCount;
 
         public void onTypefaceRetrieved(Typeface typeface) {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
index 32ea9cf..a2b62f0 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
@@ -19,7 +19,6 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Audio.Media;
 import android.support.test.runner.AndroidJUnit4;
@@ -29,6 +28,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * This class contains fake data and convenient methods for testing:
  * {@link MediaStore.Audio.Media}
@@ -52,18 +54,18 @@
 @RunWith(AndroidJUnit4.class)
 public class MediaStoreAudioTestHelper {
     public static abstract class MockAudioMediaInfo {
-        public abstract ContentValues getContentValues(boolean isInternal);
+        public abstract ContentValues getContentValues(String volumeName);
 
-        public Uri insertToInternal(ContentResolver contentResolver) {
-            Uri uri = contentResolver.insert(Media.INTERNAL_CONTENT_URI, getContentValues(true));
-            Assert.assertNotNull(uri);
-            return uri;
-        }
+        public Uri insert(ContentResolver contentResolver, String volumeName) {
+            final Uri dirUri = MediaStore.Audio.Media.getContentUri(volumeName);
+            final ContentValues values = getContentValues(volumeName);
+            contentResolver.delete(dirUri, MediaStore.Audio.Media.DATA + "=?", new String[] {
+                    values.getAsString(MediaStore.Audio.Media.DATA)
+            });
 
-        public Uri insertToExternal(ContentResolver contentResolver) {
-            Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, getContentValues(false));
-            Assert.assertNotNull(uri);
-            return uri;
+            final Uri itemUri = contentResolver.insert(dirUri, values);
+            Assert.assertNotNull(itemUri);
+            return itemUri;
         }
 
         public int delete(ContentResolver contentResolver, Uri uri) {
@@ -82,50 +84,37 @@
         }
 
         public static final int IS_RINGTONE = 0;
-
         public static final int IS_NOTIFICATION = 0;
-
         public static final int IS_ALARM = 0;
-
         public static final int IS_MUSIC = 1;
-
-        public static final int IS_DRM = 0;
-
         public static final int YEAR = 1992;
-
         public static final int TRACK = 1;
-
         public static final int DURATION = 340000;
-
         public static final String COMPOSER = "Bruce Swedien";
-
         public static final String ARTIST = "Michael Jackson";
-
         public static final String ALBUM = "Dangerous";
-
         public static final String TITLE = "Jam";
-
         public static final int SIZE = 2737870;
-
         public static final String MIME_TYPE = "audio/x-mpeg";
-
         public static final String DISPLAY_NAME = "Jam -Michael Jackson";
-
-        public static final String INTERNAL_DATA =
-            "/data/data/android.provider.cts/files/Jam.mp3";
-
         public static final String FILE_NAME = "Jam.mp3";
-
-        public static final String EXTERNAL_DATA = Environment.getExternalStorageDirectory() +
-                "/" + FILE_NAME;
-
         public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
-
         public static final String GENRE = "POP";
+
         @Override
-        public ContentValues getContentValues(boolean isInternal) {
+        public ContentValues getContentValues(String volumeName) {
             ContentValues values = new ContentValues();
-            values.put(Media.DATA, isInternal ? INTERNAL_DATA : EXTERNAL_DATA);
+            try {
+                final File data;
+                if (MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
+                    data = new File("/data/data/android.provider.cts/files/", FILE_NAME);
+                } else {
+                    data = new File(ProviderTestUtils.stageDir(volumeName), FILE_NAME);
+                }
+                values.put(Media.DATA, data.getAbsolutePath());
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
             values.put(Media.DATE_MODIFIED, DATE_MODIFIED);
             values.put(Media.DISPLAY_NAME, DISPLAY_NAME);
             values.put(Media.MIME_TYPE, MIME_TYPE);
@@ -141,8 +130,6 @@
             values.put(Media.IS_ALARM, IS_ALARM);
             values.put(Media.IS_NOTIFICATION, IS_NOTIFICATION);
             values.put(Media.IS_RINGTONE, IS_RINGTONE);
-            values.put(Media.IS_DRM, IS_DRM);
-
             return values;
         }
     }
@@ -158,53 +145,38 @@
         }
 
         public static final int IS_RINGTONE = 1;
-
         public static final int IS_NOTIFICATION = 0;
-
         public static final int IS_ALARM = 0;
-
         public static final int IS_MUSIC = 0;
-
-        public static final int IS_DRM = 0;
-
         public static final int YEAR = 1992;
-
         public static final int TRACK = 1001;
-
         public static final int DURATION = 338000;
-
         public static final String COMPOSER = "Bruce Swedien";
-
         public static final String ARTIST =
             "Michael Jackson - Live And Dangerous - National Stadium Bucharest";
-
         public static final String ALBUM =
             "Michael Jackson - Live And Dangerous - National Stadium Bucharest";
-
         public static final String TITLE = "Jam";
-
         public static final int SIZE = 2737321;
-
         public static final String MIME_TYPE = "audio/x-mpeg";
-
         public static final String DISPLAY_NAME = "Jam(Live)-Michael Jackson";
-
         public static final String FILE_NAME = "Jam_live.mp3";
-
-        public static final String EXTERNAL_DATA =
-            Environment.getExternalStorageDirectory().getPath() + "/" + FILE_NAME;
-
-        public static final String INTERNAL_DATA =
-            "/data/data/android.provider.cts/files/Jam_live.mp3";
-
-
-
         public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
 
         @Override
-        public ContentValues getContentValues(boolean isInternal) {
+        public ContentValues getContentValues(String volumeName) {
             ContentValues values = new ContentValues();
-            values.put(Media.DATA, isInternal ? INTERNAL_DATA : EXTERNAL_DATA);
+            try {
+                final File data;
+                if (MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
+                    data = new File("/data/data/android.provider.cts/files/", FILE_NAME);
+                } else {
+                    data = new File(ProviderTestUtils.stageDir(volumeName), FILE_NAME);
+                }
+                values.put(Media.DATA, data.getAbsolutePath());
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
             values.put(Media.DATE_MODIFIED, DATE_MODIFIED);
             values.put(Media.DISPLAY_NAME, DISPLAY_NAME);
             values.put(Media.MIME_TYPE, MIME_TYPE);
@@ -220,8 +192,6 @@
             values.put(Media.IS_ALARM, IS_ALARM);
             values.put(Media.IS_NOTIFICATION, IS_NOTIFICATION);
             values.put(Media.IS_RINGTONE, IS_RINGTONE);
-            values.put(Media.IS_DRM, IS_DRM);
-
             return values;
         }
     }
@@ -237,8 +207,8 @@
         }
 
         @Override
-        public ContentValues getContentValues(boolean isInternal) {
-            ContentValues values = super.getContentValues(isInternal);
+        public ContentValues getContentValues(String volumeName) {
+            ContentValues values = super.getContentValues(volumeName);
             values.put(Media.DATA, values.getAsString(Media.DATA) + "_3");
             return values;
         }
@@ -255,8 +225,8 @@
         }
 
         @Override
-        public ContentValues getContentValues(boolean isInternal) {
-            ContentValues values = super.getContentValues(isInternal);
+        public ContentValues getContentValues(String volumeName) {
+            ContentValues values = super.getContentValues(volumeName);
             values.put(Media.DATA, values.getAsString(Media.DATA) + "_4");
             return values;
         }
@@ -273,8 +243,8 @@
         }
 
         @Override
-        public ContentValues getContentValues(boolean isInternal) {
-            ContentValues values = super.getContentValues(isInternal);
+        public ContentValues getContentValues(String volumeName) {
+            ContentValues values = super.getContentValues(volumeName);
             values.put(Media.DATA, values.getAsString(Media.DATA) + "_5");
             return values;
         }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
index 0b1dad8..c027004 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
@@ -24,10 +26,14 @@
 import android.net.Uri;
 import android.provider.MediaStore;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.util.List;
 
@@ -35,8 +41,28 @@
  * Tests to verify that common actions on {@link MediaStore} content are
  * available.
  */
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStoreIntentsTest {
+    private Uri mExternalAudio;
+    private Uri mExternalVideo;
+    private Uri mExternalImages;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
+        mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+    }
+
     public void assertCanBeHandled(Intent intent) {
         List<ResolveInfo> resolveInfoList = InstrumentationRegistry.getTargetContext()
                 .getPackageManager().queryIntentActivities(intent, 0);
@@ -48,35 +74,35 @@
     @Test
     public void testPickImageDir() {
         Intent intent = new Intent(Intent.ACTION_PICK);
-        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+        intent.setData(mExternalImages);
         assertCanBeHandled(intent);
     }
 
     @Test
     public void testPickVideoDir() {
         Intent intent = new Intent(Intent.ACTION_PICK);
-        intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
+        intent.setData(mExternalVideo);
         assertCanBeHandled(intent);
     }
 
     @Test
     public void testPickAudioDir() {
         Intent intent = new Intent(Intent.ACTION_PICK);
-        intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
+        intent.setData(mExternalAudio);
         assertCanBeHandled(intent);
     }
 
     @Test
     public void testViewImageDir() {
         Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+        intent.setData(mExternalImages);
         assertCanBeHandled(intent);
     }
 
     @Test
     public void testViewVideoDir() {
         Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
+        intent.setData(mExternalVideo);
         assertCanBeHandled(intent);
     }
 
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
index 40ce7a8..2d15765 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
@@ -16,6 +16,10 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+import static android.provider.cts.ProviderTestUtils.containsId;
+import static android.provider.cts.ProviderTestUtils.hash;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -33,47 +37,54 @@
 import android.provider.MediaStore.MediaColumns;
 import android.provider.MediaStore.PendingParams;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import libcore.io.IoUtils;
+import android.util.Log;
 
 import com.google.common.base.Objects;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.regex.Pattern;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStorePendingTest {
     private Context mContext;
     private ContentResolver mResolver;
 
-    private Uri mExternalAudio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-    private Uri mExternalVideo = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-    private Uri mExternalImages = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-    private Uri mExternalDownloads = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
+    private Uri mExternalAudio;
+    private Uri mExternalVideo;
+    private Uri mExternalImages;
+    private Uri mExternalDownloads;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
 
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mResolver = mContext.getContentResolver();
-    }
 
-    @After
-    public void tearDown() throws Exception {
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
+        mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+        mExternalDownloads = MediaStore.Downloads.getContentUri(mVolumeName);
     }
 
     @Test
@@ -107,15 +118,12 @@
 
         // Write an image into place
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.scenery);
                  OutputStream out = session.openOutputStream()) {
                 FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         // Verify pending status across various queries
@@ -149,8 +157,7 @@
         final Uri pendingUri = MediaStore.createPending(mContext, params);
         final File pendingFile;
 
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.scenery);
                     OutputStream out = session.openOutputStream()) {
                 FileUtils.copy(in, out);
@@ -161,8 +168,6 @@
             getRawFileHash(pendingFile);
 
             session.abandon();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         // Should have no record of abandoned item
@@ -412,28 +417,15 @@
 
     private Uri execPending(PendingParams params, int resId) throws Exception {
         final Uri pendingUri = MediaStore.createPending(mContext, params);
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(resId);
                     OutputStream out = session.openOutputStream()) {
                 FileUtils.copy(in, out);
             }
             return session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
     }
 
-    private boolean containsId(Uri uri, long id) {
-        try (Cursor c = mResolver.query(uri,
-                new String[] { MediaColumns._ID }, null, null)) {
-            while (c.moveToNext()) {
-                if (c.getLong(0) == id) return true;
-            }
-        }
-        return false;
-    }
-
     private static File getRawFile(Uri uri) throws Exception {
         final String res = ProviderTestUtils.executeShellCommand(
                 "content query --uri " + uri + " --projection _data",
@@ -456,15 +448,4 @@
             throw new FileNotFoundException("Failed to find hash for " + file + "; found " + res);
         }
     }
-
-    private static byte[] hash(InputStream in) throws Exception {
-        try (DigestInputStream digestIn = new DigestInputStream(in,
-                MessageDigest.getInstance("SHA-1"));
-                OutputStream out = new FileOutputStream(new File("/dev/null"))) {
-            FileUtils.copy(digestIn, out);
-            return digestIn.getMessageDigest().digest();
-        } finally {
-            IoUtils.closeQuietly(in);
-        }
-    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
index ffb3afb..6104f61 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
@@ -19,26 +19,22 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.app.usage.StorageStatsManager;
 import android.content.ContentResolver;
 import android.content.ContentUris;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
-import android.media.MediaScanner;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.SystemClock;
 import android.os.storage.StorageManager;
 import android.provider.MediaStore;
 import android.provider.MediaStore.MediaColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import libcore.util.HexEncoding;
 
@@ -47,6 +43,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
 import java.io.OutputStream;
@@ -55,76 +54,51 @@
 import java.util.Set;
 import java.util.UUID;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStoreTest {
-    private static final String TEST_VOLUME_NAME = "volume_for_cts";
+    static final String TAG = "MediaStoreTest";
 
     private static final long SIZE_DELTA = 32_000;
 
-    private static final String[] PROJECTION = new String[] { MediaStore.MEDIA_SCANNER_VOLUME };
-
-    private Uri mScannerUri;
-
-    private String mVolumnBackup;
-
+    private Context mContext;
     private ContentResolver mContentResolver;
 
+    private Uri mExternalImages;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     private Context getContext() {
         return InstrumentationRegistry.getTargetContext();
     }
 
     @Before
     public void setUp() throws Exception {
-        mScannerUri = MediaStore.getMediaScannerUri();
-        mContentResolver = getContext().getContentResolver();
+        mContext = InstrumentationRegistry.getTargetContext();
+        mContentResolver = mContext.getContentResolver();
 
-        Cursor c = mContentResolver.query(mScannerUri, PROJECTION, null, null, null);
-        if (c != null) {
-            c.moveToFirst();
-            mVolumnBackup = c.getString(0);
-            c.close();
-        }
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
     }
 
     @After
     public void tearDown() throws Exception {
         InstrumentationRegistry.getInstrumentation().getUiAutomation()
                 .dropShellPermissionIdentity();
-
-        // restore initial values
-        if (mVolumnBackup != null) {
-            ContentValues values = new ContentValues();
-            values.put(MediaStore.MEDIA_SCANNER_VOLUME, mVolumnBackup);
-            mContentResolver.insert(mScannerUri, values);
-        }
     }
 
     @Test
     public void testGetMediaScannerUri() {
-        ContentValues values = new ContentValues();
-        String selection = MediaStore.MEDIA_SCANNER_VOLUME + "=?";
-        String[] selectionArgs = new String[] { TEST_VOLUME_NAME };
-
-        // assert there is no item with name TEST_VOLUME_NAME
-        assertNull(mContentResolver.query(mScannerUri, PROJECTION,
-                selection, selectionArgs, null));
-
-        // insert
-        values.put(MediaStore.MEDIA_SCANNER_VOLUME, TEST_VOLUME_NAME);
-        assertEquals(MediaStore.getMediaScannerUri(),
-                mContentResolver.insert(mScannerUri, values));
-
         // query
-        Cursor c = mContentResolver.query(mScannerUri, PROJECTION,
-                selection, selectionArgs, null);
+        Cursor c = mContentResolver.query(MediaStore.getMediaScannerUri(), null,
+                null, null, null);
         assertEquals(1, c.getCount());
-        c.moveToFirst();
-        assertEquals(TEST_VOLUME_NAME, c.getString(0));
         c.close();
-
-        // delete
-        assertEquals(1, mContentResolver.delete(mScannerUri, null, null));
-        assertNull(mContentResolver.query(mScannerUri, PROJECTION, null, null, null));
     }
 
     @Test
@@ -138,19 +112,28 @@
         Set<String> volumeNames = MediaStore.getAllVolumeNames(getContext());
 
         // At very least should contain these two volumes
-        assertTrue(volumeNames.contains("internal"));
-        assertTrue(volumeNames.contains("external"));
+        assertTrue(volumeNames.contains(MediaStore.VOLUME_INTERNAL));
+        assertTrue(volumeNames.contains(MediaStore.VOLUME_EXTERNAL));
     }
 
     @Test
     public void testContributedMedia() throws Exception {
         // STOPSHIP: remove this once isolated storage is always enabled
         Assume.assumeTrue(StorageManager.hasIsolatedStorage());
+        Assume.assumeTrue(MediaStore.VOLUME_EXTERNAL.equals(mVolumeName));
 
         InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
                 android.Manifest.permission.CLEAR_APP_USER_DATA,
                 android.Manifest.permission.PACKAGE_USAGE_STATS);
 
+        // Start by cleaning up contributed items
+        MediaStore.deleteContributedMedia(getContext(), getContext().getPackageName(),
+                android.os.Process.myUserHandle());
+
+        // Force sync to try updating other views
+        ProviderTestUtils.executeShellCommand("sync");
+        SystemClock.sleep(500);
+
         // Measure usage before
         final long beforePackage = getExternalPackageSize();
         final long beforeTotal = getExternalTotalSize();
@@ -166,22 +149,21 @@
         // Create media both inside and outside sandbox
         final Uri inside;
         final Uri outside;
-        final File file = new File(getContext().getExternalMediaDirs()[0],
-                "cts" + System.nanoTime());
+        final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "cts" + System.nanoTime() + ".jpg");
         ProviderTestUtils.stageFile(R.raw.volantis, file);
-        try (MediaScanner scanner = new MediaScanner(getContext(), "external")) {
-            inside = scanner.scanSingleFile(file.getAbsolutePath(), "image/jpeg");
-        }
-        outside = ProviderTestUtils.stageMedia(R.raw.volantis,
-                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
-        SystemClock.sleep(500);
+        inside = ProviderTestUtils.scanFile(file);
+        outside = ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages);
 
         {
-            final HashSet<Long> visible = getVisibleIds(
-                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+            final HashSet<Long> visible = getVisibleIds(mExternalImages);
             assertTrue(visible.contains(ContentUris.parseId(inside)));
             assertTrue(visible.contains(ContentUris.parseId(outside)));
 
+            // Force sync to try updating other views
+            ProviderTestUtils.executeShellCommand("sync");
+            SystemClock.sleep(500);
+
             final long afterPackage = getExternalPackageSize();
             final long afterTotal = getExternalTotalSize();
             final long afterContributed = MediaStore.getContributedMediaSize(getContext(),
@@ -195,13 +177,15 @@
         // Delete only contributed items
         MediaStore.deleteContributedMedia(getContext(), getContext().getPackageName(),
                 android.os.Process.myUserHandle());
-        SystemClock.sleep(500);
         {
-            final HashSet<Long> visible = getVisibleIds(
-                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+            final HashSet<Long> visible = getVisibleIds(mExternalImages);
             assertTrue(visible.contains(ContentUris.parseId(inside)));
             assertFalse(visible.contains(ContentUris.parseId(outside)));
 
+            // Force sync to try updating other views
+            ProviderTestUtils.executeShellCommand("sync");
+            SystemClock.sleep(500);
+
             final long afterPackage = getExternalPackageSize();
             final long afterTotal = getExternalTotalSize();
             final long afterContributed = MediaStore.getContributedMediaSize(getContext(),
@@ -217,8 +201,7 @@
     public void testHash() throws Exception {
         final ContentResolver resolver = getContext().getContentResolver();
 
-        final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis,
-                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+        final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages);
         SystemClock.sleep(500);
 
         final String expected = Arrays
@@ -246,7 +229,7 @@
         final StorageManager storage = getContext().getSystemService(StorageManager.class);
         final StorageStatsManager stats = getContext().getSystemService(StorageStatsManager.class);
 
-        final UUID externalUuid = storage.getUuidForPath(Environment.getExternalStorageDirectory());
+        final UUID externalUuid = storage.getUuidForPath(MediaStore.getVolumePath(mVolumeName));
         return stats.queryStatsForPackage(externalUuid, getContext().getPackageName(),
                 android.os.Process.myUserHandle()).getDataBytes();
     }
@@ -255,7 +238,7 @@
         final StorageManager storage = getContext().getSystemService(StorageManager.class);
         final StorageStatsManager stats = getContext().getSystemService(StorageStatsManager.class);
 
-        final UUID externalUuid = storage.getUuidForPath(Environment.getExternalStorageDirectory());
+        final UUID externalUuid = storage.getUuidForPath(MediaStore.getVolumePath(mVolumeName));
         return stats.queryExternalStatsForUser(externalUuid, android.os.Process.myUserHandle())
                 .getTotalBytes();
     }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
index 24a0c53..97cd1ff 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -30,30 +32,43 @@
 import android.provider.MediaStore;
 import android.provider.MediaStore.MediaColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
 import android.text.format.DateUtils;
 import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStoreTrashTest {
-    private static final String TAG = "MediaStoreTrashTest";
-
     private Context mContext;
     private ContentResolver mResolver;
 
+    private Uri mExternalImages;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
     }
 
     @Test
     public void testTrashUntrash() throws Exception {
-        final Uri insertUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+        final Uri insertUri = mExternalImages;
         final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, insertUri);
         final long id = ContentUris.parseId(uri);
 
@@ -93,7 +108,7 @@
 
     @Test
     public void testTrashExecutes() throws Exception {
-        final Uri insertUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+        final Uri insertUri = mExternalImages;
         final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, insertUri);
 
         MediaStore.trash(mContext, uri, 1);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
index 609604f..079fec4 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -23,68 +25,65 @@
 import static org.junit.Assert.fail;
 
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
+import android.graphics.BitmapFactory;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Audio.Albums;
 import android.provider.MediaStore.Audio.Media;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.util.Size;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_AlbumsTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Albums.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+                Albums.getContentUri(mVolumeName), null, null,
                 null, null));
         c.close();
-        assertNotNull(c = mContentResolver.query(
-                Albums.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
-                null, null));
-        c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Albums.getContentUri(volume), null, null, null, null));
     }
 
     @Test
-    public void testStoreAudioAlbumsInternal() {
-        doStoreAudioAlbums(true);
-    }
-
-    @Test
-    public void testStoreAudioAlbumsExternal() {
-        doStoreAudioAlbums(false);
-    }
-
-    private void doStoreAudioAlbums(boolean isInternal) {
+    public void testStoreAudioAlbums() {
         // do not support direct insert operation of the albums
-        Uri audioAlbumsUri = isInternal? Albums.INTERNAL_CONTENT_URI : Albums.EXTERNAL_CONTENT_URI;
+        Uri audioAlbumsUri = Albums.getContentUri(mVolumeName);
         try {
             mContentResolver.insert(audioAlbumsUri, new ContentValues());
             fail("Should throw UnsupportedOperationException!");
@@ -94,8 +93,7 @@
 
         // the album item is inserted when inserting audio media
         Audio1 audio1 = Audio1.getInstance();
-        Uri audioMediaUri = isInternal ? audio1.insertToInternal(mContentResolver)
-                : audio1.insertToExternal(mContentResolver);
+        Uri audioMediaUri = audio1.insert(mContentResolver, mVolumeName);
 
         String selection = Albums.ALBUM +"=?";
         String[] selectionArgs = new String[] { Audio1.ALBUM };
@@ -174,57 +172,61 @@
     }
 
     @Test
-    public void testAlbumArt() {
-        File path = new File(Environment.getExternalStorageDirectory()
-                + "/test" + System.currentTimeMillis() + ".mp3");
-        Uri uri = null;
+    public void testAlbumArt() throws Exception {
+        final File dir = ProviderTestUtils.stageDir(mVolumeName);
+        final File path = new File(dir, "test" + System.currentTimeMillis() + ".mp3");
         try {
-            File dir = path.getParentFile();
-            dir.mkdirs();
             ProviderTestUtils.stageFile(R.raw.testmp3, path);
 
             ContentValues v = new ContentValues();
             v.put(Media.DATA, path.getAbsolutePath());
             v.put(Media.TITLE, "testing");
             v.put(Albums.ALBUM, "test" + System.currentTimeMillis());
-            uri = mContentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, v);
-            AssetFileDescriptor afd = mContentResolver.openAssetFileDescriptor(
-                    uri.buildUpon().appendPath("albumart").build(), "r");
-            assertNotNull(afd);
-            afd.close();
 
-            Cursor c = mContentResolver.query(uri, null, null, null, null);
-            c.moveToFirst();
-            long aid = c.getLong(c.getColumnIndex(Albums.ALBUM_ID));
-            c.close();
+            final Uri mediaUri = mContentResolver
+                    .insert(MediaStore.Audio.Media.getContentUri(mVolumeName), v);
+            final long mediaId = ContentUris.parseId(mediaUri);
 
-            Uri albumart = Uri.parse("content://media/external/audio/albumart/" + aid);
-            try {
-                mContentResolver.delete(albumart, null, null);
-                afd = mContentResolver.openAssetFileDescriptor(albumart, "r");
-            } catch (FileNotFoundException e) {
-                fail("no album art");
+            final long albumId;
+            try (Cursor c = mContentResolver.query(mediaUri, null, null, null, null)) {
+                assertTrue(c.moveToFirst());
+                albumId = c.getLong(c.getColumnIndex(Albums.ALBUM_ID));
             }
 
-            c = mContentResolver.query(albumart, null, null, null, null);
-            c.moveToFirst();
-            String albumartfile = c.getString(c.getColumnIndex("_data"));
-            c.close();
-            new File(albumartfile).delete();
+            // Verify that normal thumbnails work
+            assertNotNull(mContentResolver.loadThumbnail(mediaUri, new Size(32, 32), null));
+
+            // Verify that hidden APIs still work to obtain album art
+            final Uri byMedia = MediaStore.AUTHORITY_URI.buildUpon().appendPath(mVolumeName)
+                    .appendPath("audio").appendPath("media")
+                    .appendPath(Long.toString(mediaId)).appendPath("albumart").build();
+            final Uri byAlbum = MediaStore.AUTHORITY_URI.buildUpon().appendPath(mVolumeName)
+                    .appendPath("audio").appendPath("albumart")
+                    .appendPath(Long.toString(albumId)).build();
+            assertNotNull(BitmapFactory.decodeStream(mContentResolver.openInputStream(byMedia)));
+            assertNotNull(BitmapFactory.decodeStream(mContentResolver.openInputStream(byAlbum)));
+
+            // Delete item and confirm art is cleaned up
+            mContentResolver.delete(mediaUri, null, null);
+
             try {
-                afd = mContentResolver.openAssetFileDescriptor(albumart, "r");
-            } catch (FileNotFoundException e) {
-                fail("no album art");
+                mContentResolver.loadThumbnail(mediaUri, new Size(32, 32), null);
+                fail();
+            } catch (IOException expected) {
+            }
+            try {
+                BitmapFactory.decodeStream(mContentResolver.openInputStream(byMedia));
+                fail();
+            } catch (IOException expected) {
+            }
+            try {
+                BitmapFactory.decodeStream(mContentResolver.openInputStream(byAlbum));
+                fail();
+            } catch (IOException expected) {
             }
 
-        } catch (Exception e) {
-            fail("album art failed " + e);
         } finally {
             path.delete();
-            if (uri != null) {
-                mContentResolver.delete(uri, null, null);
-            }
         }
     }
-
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
index 9f923e5..60950d1 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -31,52 +33,48 @@
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_ArtistsTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Artists.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
-                    null, null));
-        c.close();
-        assertNotNull(c = mContentResolver.query(
-                Artists.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+                Artists.getContentUri(mVolumeName), null, null,
                 null, null));
         c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Artists.getContentUri(volume), null, null, null, null));
     }
 
     @Test
-    public void testStoreAudioArtistsInternal() {
-        doStoreAudioArtists(true);
-    }
-
-    @Test
-    public void testStoreAudioArtistsExternal() {
-        doStoreAudioArtists(false);
-    }
-
-    private void doStoreAudioArtists(boolean isInternal) {
-        Uri artistsUri = isInternal ? Artists.INTERNAL_CONTENT_URI : Artists.EXTERNAL_CONTENT_URI;
+    public void testStoreAudioArtists() {
+        Uri artistsUri = Artists.getContentUri(mVolumeName);
         // do not support insert operation of the artists
         try {
             mContentResolver.insert(artistsUri, new ContentValues());
@@ -85,8 +83,7 @@
             // expected
         }
         // the artist items are inserted when inserting audio media
-        Uri uri = isInternal ? Audio1.getInstance().insertToInternal(mContentResolver)
-                : Audio1.getInstance().insertToExternal(mContentResolver);
+        Uri uri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
 
         String selection = Artists.ARTIST + "=?";
         String[] selectionArgs = new String[] { Audio1.ARTIST };
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
index 3b5282d..bba1e1a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -32,65 +34,55 @@
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_Artists_AlbumsTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
-        Uri contentUri = MediaStore.Audio.Artists.Albums.getContentUri(
-                MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME, 1);
+        Uri contentUri = MediaStore.Audio.Artists.Albums.getContentUri(mVolumeName, 1);
         assertNotNull(c = mContentResolver.query(contentUri, null, null, null, null));
         c.close();
-
-        contentUri = MediaStore.Audio.Artists.Albums.getContentUri(
-                MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, 1);
-        assertNotNull(c = mContentResolver.query(contentUri, null, null, null, null));
-        c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(MediaStore.Audio.Artists.Albums.getContentUri(volume, 1),
-                null, null, null, null));
     }
 
     @Test
-    public void testStoreAudioArtistsAlbumsInternal() {
-        doStoreAudioArtistsAlbums(true);
-    }
-
-    @Test
-    public void testStoreAudioArtistsAlbumsExternal() {
-        doStoreAudioArtistsAlbums(false);
-    }
-
-    private void doStoreAudioArtistsAlbums(boolean isInternal) {
+    public void testStoreAudioArtistsAlbums() {
         // the album item is inserted when inserting audio media
-        Uri audioMediaUri = isInternal ? Audio1.getInstance().insertToInternal(mContentResolver)
-                : Audio1.getInstance().insertToExternal(mContentResolver);
+        Uri audioMediaUri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
         // get artist id
         Cursor c = mContentResolver.query(audioMediaUri, new String[] { Media.ARTIST_ID }, null,
                 null, null);
         c.moveToFirst();
         Long artistId = c.getLong(c.getColumnIndex(Media.ARTIST_ID));
         c.close();
-        Uri artistsAlbumsUri = MediaStore.Audio.Artists.Albums.getContentUri(isInternal ?
-                MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME :
-                    MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, artistId);
+        Uri artistsAlbumsUri = MediaStore.Audio.Artists.Albums.getContentUri(mVolumeName, artistId);
         // do not support insert operation of the albums
         try {
             mContentResolver.insert(artistsAlbumsUri, new ContentValues());
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
index 07d4912..c675059 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -32,31 +34,43 @@
 import android.net.Uri;
 import android.provider.MediaStore.Audio.Genres;
 import android.provider.MediaStore.Audio.Genres.Members;
-import android.provider.MediaStore.Audio.Media;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_GenresTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Genres.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
+                Genres.getContentUri(mVolumeName), null, null,
                     null, null));
         c.close();
         try {
@@ -68,10 +82,6 @@
         } catch (SQLException e) {
             // expected
         }
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Genres.getContentUri(volume), null, null, null, null));
     }
 
     @Test
@@ -79,7 +89,7 @@
         // insert
         ContentValues values = new ContentValues();
         values.put(Genres.NAME, "POP");
-        Uri uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
         assertNotNull(uri);
 
         try {
@@ -107,33 +117,30 @@
     @Test
     public void testGetContentUriForAudioId() {
         // Insert an audio file into the content provider.
-        ContentValues values = Audio1.getInstance().getContentValues(true);
-        Uri audioUri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+        Uri audioUri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
         assertNotNull(audioUri);
         long audioId = ContentUris.parseId(audioUri);
         assertTrue(audioId != -1);
 
         // Insert a genre into the content provider.
-        values.clear();
+        ContentValues values = new ContentValues();
         values.put(Genres.NAME, "Soda Pop");
-        Uri genreUri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+        Uri genreUri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
         assertNotNull(genreUri);
         long genreId = ContentUris.parseId(genreUri);
         assertTrue(genreId != -1);
 
         Cursor cursor = null;
         try {
-            String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
-
             // Check that the audio file has no genres yet.
-            Uri audioGenresUri = Genres.getContentUriForAudioId(volumeName, (int) audioId);
+            Uri audioGenresUri = Genres.getContentUriForAudioId(mVolumeName, (int) audioId);
             cursor = mContentResolver.query(audioGenresUri, null, null, null, null);
             assertFalse(cursor.moveToNext());
 
             // Link the audio file to the genre.
             values.clear();
             values.put(Members.AUDIO_ID, audioId);
-            Uri membersUri = Members.getContentUri(volumeName, genreId);
+            Uri membersUri = Members.getContentUri(mVolumeName, genreId);
             assertNotNull(mContentResolver.insert(membersUri, values));
 
             // Check that the audio file has the genre it was linked to.
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
index 1b2c73d..9d704cb 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -23,26 +25,42 @@
 import static org.junit.Assert.fail;
 
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.SQLException;
 import android.net.Uri;
+import android.provider.MediaStore;
 import android.provider.MediaStore.Audio.Genres;
 import android.provider.MediaStore.Audio.Genres.Members;
 import android.provider.MediaStore.Audio.Media;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
 import android.support.test.InstrumentationRegistry;
+import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_Genres_MembersTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     private long mAudioIdOfJam;
 
     private long mAudioIdOfJamLive;
@@ -52,13 +70,15 @@
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
 
-        Uri uri = Audio1.getInstance().insertToExternal(mContentResolver);
+        Log.d(TAG, "Using volume " + mVolumeName);
+
+        Uri uri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
         Cursor c = mContentResolver.query(uri, null, null, null, null);
         c.moveToFirst();
         mAudioIdOfJam = c.getLong(c.getColumnIndex(Media._ID));
         c.close();
 
-        uri = Audio2.getInstance().insertToExternal(mContentResolver);
+        uri = Audio2.getInstance().insert(mContentResolver, mVolumeName);
         c = mContentResolver.query(uri, null, null, null, null);
         c.moveToFirst();
         mAudioIdOfJamLive = c.getLong(c.getColumnIndex(Media._ID));
@@ -69,16 +89,17 @@
     public void tearDown() throws Exception {
         // "jam" should already have been deleted as part of the test, but delete it again just
         // in case the test failed and aborted before that.
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJam, null);
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJamLive,
-                null);
+        mContentResolver.delete(Media.getContentUri(mVolumeName),
+                Media._ID + "=" + mAudioIdOfJam, null);
+        mContentResolver.delete(Media.getContentUri(mVolumeName),
+                Media._ID + "=" + mAudioIdOfJamLive, null);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, 1), null,
+                Members.getContentUri(mVolumeName, 1), null,
                     null, null, null));
         c.close();
 
@@ -91,18 +112,13 @@
         } catch (SQLException e) {
             // expected
         }
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Members.getContentUri(volume, 1), null, null, null,
-                null));
     }
 
     @Test
     public void testStoreAudioGenresMembersExternal() {
         ContentValues values = new ContentValues();
         values.put(Genres.NAME, Audio1.GENRE);
-        Uri uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
         Cursor c = mContentResolver.query(uri, null, null, null, null);
         c.moveToFirst();
 
@@ -111,13 +127,13 @@
         c.close();
 
         // verify that the Uri has the correct format and genre value
-        assertEquals(uri.toString(), "content://media/external/audio/genres/" + genreId);
+        assertEquals(ContentUris.withAppendedId(Genres.getContentUri(mVolumeName), genreId),
+                uri);
 
         // insert audio as the member of the genre
         values.clear();
         values.put(Members.AUDIO_ID, mAudioIdOfJam);
-        Uri membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                genreId);
+        Uri membersUri = Members.getContentUri(mVolumeName, genreId);
         assertNotNull(mContentResolver.insert(membersUri, values));
 
         try {
@@ -130,7 +146,9 @@
             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members.AUDIO_ID)));
             assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
             assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members._ID)));
-            assertEquals(Audio1.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+            final String expected1 = Audio1.getInstance().getContentValues(mVolumeName)
+                    .getAsString(Members.DATA);
+            assertEquals(expected1, c.getString(c.getColumnIndex(Members.DATA)));
             assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
             assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
             assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
@@ -138,7 +156,6 @@
             assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
             assertEquals(Audio1.TITLE, c.getString(c.getColumnIndex(Members.TITLE)));
             assertEquals(Audio1.ALBUM, c.getString(c.getColumnIndex(Members.ALBUM)));
-            assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
             String albumKey = c.getString(c.getColumnIndex(Members.ALBUM_KEY));
             assertNotNull(albumKey);
             long albumId = c.getLong(c.getColumnIndex(Members.ALBUM_ID));
@@ -182,7 +199,9 @@
             c.close();
 
             // Query members across all genres
-            Uri allMembersUri = Uri.parse("content://media/external/audio/genres/all/members");
+            // TODO: migrate this to using public API
+            Uri allMembersUri = MediaStore.Audio.Genres.getContentUri(mVolumeName).buildUpon()
+                    .appendPath("all").appendPath("members").build();
             c = mContentResolver.query(allMembersUri, null, null, null, null);
             int colidx = c.getColumnIndex(Members.AUDIO_ID);
             int jamcnt = 0;
@@ -208,7 +227,7 @@
             // create another genre
             values.clear();
             values.put(Genres.NAME, Audio1.GENRE + "-2");
-            uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+            uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
             c = mContentResolver.query(uri, null, null, null, null);
             c.moveToFirst();
             genre2Id = c.getLong(c.getColumnIndex(Genres._ID));
@@ -217,8 +236,7 @@
             // insert the song into the second genre
             values.clear();
             values.put(Members.AUDIO_ID, mAudioIdOfJam);
-            Uri members2Uri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                genre2Id);
+            Uri members2Uri = Members.getContentUri(mVolumeName, genre2Id);
             assertNotNull(mContentResolver.insert(members2Uri, values));
 
             // Query members across all genres again
@@ -260,8 +278,7 @@
             // insert again, then verify that deleting the audio entry cleans up its genre member
             // entry as well
             values.put(Members.AUDIO_ID, mAudioIdOfJam);
-            membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                    genreId);
+            membersUri = Members.getContentUri(mVolumeName, genreId);
             assertNotNull(mContentResolver.insert(membersUri, values));
             // Query members across all genres
             c = mContentResolver.query(allMembersUri,
@@ -277,7 +294,7 @@
             }
             assertEquals(1, jamcnt);
             c.close();
-            mContentResolver.delete(Media.EXTERNAL_CONTENT_URI,
+            mContentResolver.delete(Media.getContentUri(mVolumeName),
                     Media._ID + "=" + mAudioIdOfJam, null);
             // Query members across all genres
             c = mContentResolver.query(allMembersUri,
@@ -294,9 +311,11 @@
             c.close();
         } finally {
             // the members are deleted when deleting the genre which they belong to
-            mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genreId, null);
+            mContentResolver.delete(Genres.getContentUri(mVolumeName),
+                    Genres._ID + "=" + genreId, null);
             if (genre2Id >= 0) {
-                mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genre2Id, null);
+                mContentResolver.delete(Genres.getContentUri(mVolumeName),
+                        Genres._ID + "=" + genre2Id, null);
             }
             c = mContentResolver.query(membersUri, null, null, null, null);
             assertEquals(0, c.getCount());
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
index a2b760b..22f91f3 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
@@ -16,8 +16,9 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -30,40 +31,44 @@
 import android.os.Environment;
 import android.provider.MediaStore.Audio.Media;
 import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
-import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_MediaTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Media.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+                Media.getContentUri(mVolumeName), null, null,
                     null, null));
         c.close();
-        assertNotNull(c = mContentResolver.query(
-                Media.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
-                    null, null));
-        c.close();
-
-        // can not accept any other volume names
-        String volume = "faveVolume";
-        assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
     }
 
     @Test
@@ -81,20 +86,11 @@
     }
 
     @Test
-    public void testStoreAudioMediaInternal() {
-        doStoreAudioMedia(true);
-    }
-
-    @Test
-    public void testStoreAudioMediaExternal() {
-        doStoreAudioMedia(false);
-    }
-
-    private void doStoreAudioMedia(boolean isInternal) {
+    public void testStoreAudioMedia() {
         Audio1 audio1 = Audio1.getInstance();
-        ContentValues values = audio1.getContentValues(isInternal);
+        ContentValues values = audio1.getContentValues(mVolumeName);
         //insert
-        Uri mediaUri = isInternal ? Media.INTERNAL_CONTENT_URI : Media.EXTERNAL_CONTENT_URI;
+        Uri mediaUri = Media.getContentUri(mVolumeName);
         Uri uri = mContentResolver.insert(mediaUri, values);
         assertNotNull(uri);
 
@@ -108,11 +104,10 @@
             c.moveToFirst();
             long id = c.getLong(c.getColumnIndex(Media._ID));
             assertTrue(id > 0);
-            String expected = isInternal ? Audio1.INTERNAL_DATA : Audio1.EXTERNAL_DATA;
+            String expected = audio1.getContentValues(mVolumeName).getAsString(Media.DATA);
             assertEquals(expected, c.getString(c.getColumnIndex(Media.DATA)));
             assertTrue(c.getLong(c.getColumnIndex(Media.DATE_ADDED)) > 0);
             assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Media.DATE_MODIFIED)));
-            assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Media.IS_DRM)));
             assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
             assertEquals(Audio1.MIME_TYPE, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
             assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Media.SIZE)));
@@ -140,7 +135,7 @@
             c.close();
 
             // test filtering
-            Uri baseUri = isInternal ? Media.INTERNAL_CONTENT_URI : Media.EXTERNAL_CONTENT_URI;
+            Uri baseUri = Media.getContentUri(mVolumeName);
             Uri filterUri = baseUri.buildUpon()
                 .appendQueryParameter("filter", Audio1.ARTIST).build();
             c = mContentResolver.query(filterUri, null, null, null, null);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
index 846cfca..a06e93c 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -28,33 +30,45 @@
 import android.database.Cursor;
 import android.database.SQLException;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.MediaStore.Audio.Playlists;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-import java.util.regex.Pattern;
+import java.io.File;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_PlaylistsTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
     }
 
     @Test
     public void testGetContentUri() {
         Cursor c = null;
         assertNotNull(c = mContentResolver.query(
-                Playlists.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
+                Playlists.getContentUri(mVolumeName), null, null,
                 null, null));
         c.close();
 
@@ -68,16 +82,12 @@
         } catch (SQLException e) {
             // expected
         }
-
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Playlists.getContentUri(volume), null, null, null,
-                null));
     }
 
     @Test
-    public void testStoreAudioPlaylistsExternal() {
-        final String externalPlaylistPath = Environment.getExternalStorageDirectory().getPath() +
-            "/my_favorites.pl";
+    public void testStoreAudioPlaylistsExternal() throws Exception {
+        final String externalPlaylistPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "my_favorites.pl").getAbsolutePath();
         ContentValues values = new ContentValues();
         values.put(Playlists.NAME, "My favourites");
         values.put(Playlists.DATA, externalPlaylistPath);
@@ -85,7 +95,7 @@
         long dateModified = System.currentTimeMillis() / 1000;
         values.put(Playlists.DATE_MODIFIED, dateModified);
         // insert
-        Uri uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
         assertNotNull(uri);
 
         try {
@@ -106,26 +116,4 @@
             assertEquals(1, mContentResolver.delete(uri, null, null));
         }
     }
-
-    @Test
-    public void testStoreAudioPlaylistsInternal() {
-        ContentValues values = new ContentValues();
-        values.put(Playlists.NAME, "My favourites");
-        values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
-        long dateAdded = System.currentTimeMillis();
-        values.put(Playlists.DATE_ADDED, dateAdded);
-        long dateModified = System.currentTimeMillis();
-        values.put(Playlists.DATE_MODIFIED, dateModified);
-        // insert
-        Uri uri = mContentResolver.insert(Playlists.INTERNAL_CONTENT_URI, values);
-        assertNotNull(uri);
-
-        try {
-            assertTrue(Pattern.matches("content://media/internal/audio/playlists/\\d+",
-                    uri.toString()));
-        } finally {
-            // delete the playlists
-            assertEquals(1, mContentResolver.delete(uri, null, null));
-        }
-    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
index e87e10a..89b7bc5 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
@@ -16,12 +16,15 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
@@ -37,16 +40,17 @@
 import android.provider.cts.MediaStoreAudioTestHelper.Audio5;
 import android.provider.cts.MediaStoreAudioTestHelper.MockAudioMediaInfo;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
-import java.util.regex.Pattern;
-
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Audio_Playlists_MembersTest {
     private String[] mAudioProjection = {
             Members._ID,
@@ -63,7 +67,6 @@
             Members.DISPLAY_NAME,
             Members.DURATION,
             Members.IS_ALARM,
-            Members.IS_DRM,
             Members.IS_MUSIC,
             Members.IS_NOTIFICATION,
             Members.IS_RINGTONE,
@@ -93,7 +96,6 @@
             Members.DISPLAY_NAME,
             Members.DURATION,
             Members.IS_ALARM,
-            Members.IS_DRM,
             Members.IS_MUSIC,
             Members.IS_NOTIFICATION,
             Members.IS_RINGTONE,
@@ -114,8 +116,16 @@
     private long mIdOfAudio4;
     private long mIdOfAudio5;
 
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     private long insertAudioItem(MockAudioMediaInfo which) {
-        Uri uri = which.insertToExternal(mContentResolver);
+        Uri uri = which.insert(mContentResolver, mVolumeName);
         Cursor c = mContentResolver.query(uri, null, null, null, null);
         c.moveToFirst();
         long id = c.getLong(c.getColumnIndex(Media._ID));
@@ -128,6 +138,8 @@
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
 
+        Log.d(TAG, "Using volume " + mVolumeName);
+
         mIdOfAudio1 = insertAudioItem(Audio1.getInstance());
         mIdOfAudio2 = insertAudioItem(Audio2.getInstance());
         mIdOfAudio3 = insertAudioItem(Audio3.getInstance());
@@ -137,11 +149,12 @@
 
     @After
     public void tearDown() throws Exception {
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio1, null);
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio2, null);
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio3, null);
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio4, null);
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio5, null);
+        final Uri uri = Media.getContentUri(mVolumeName);
+        mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio1, null);
+        mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio2, null);
+        mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio3, null);
+        mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio4, null);
+        mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio5, null);
     }
 
     @Test
@@ -197,6 +210,9 @@
 
     @Test
     public void testStoreAudioPlaylistsMembersExternal() {
+        // TODO: expand test to verify paths from secondary storage devices
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
         ContentValues values = new ContentValues();
         values.put(Playlists.NAME, "My favourites");
         values.put(Playlists.DATA, "");
@@ -205,7 +221,7 @@
         long dateModified = System.currentTimeMillis();
         values.put(Playlists.DATE_MODIFIED, dateModified);
         // insert
-        Uri uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
         assertNotNull(uri);
         Cursor c = mContentResolver.query(uri, null, null, null, null);
         c.moveToFirst();
@@ -213,11 +229,11 @@
         long playlist2Id = -1; // used later
 
         // verify that the Uri has the correct format and playlist value
-        assertEquals(uri.toString(), "content://media/external/audio/playlists/" + playlistId);
+        assertEquals(ContentUris.withAppendedId(Playlists.getContentUri(mVolumeName), playlistId),
+                uri);
 
         // insert audio as the member of the playlist
-        Uri membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                playlistId);
+        Uri membersUri = Members.getContentUri(mVolumeName, playlistId);
         Uri audioUri = insertPlaylistItem(membersUri, mIdOfAudio1, 1);
 
         assertNotNull(audioUri);
@@ -230,10 +246,11 @@
             c.moveToFirst();
             long memberId = c.getLong(c.getColumnIndex(Members._ID));
             assertEquals(memberId, Long.parseLong(audioUri.getPathSegments().get(5)));
-            assertEquals(Audio1.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+            final String expected1 = Audio1.getInstance().getContentValues(mVolumeName)
+                    .getAsString(Members.DATA);
+            assertEquals(expected1, c.getString(c.getColumnIndex(Members.DATA)));
             assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
             assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
-            assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
             assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
             assertEquals(Audio1.MIME_TYPE, c.getString(c.getColumnIndex(Members.MIME_TYPE)));
             assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
@@ -274,10 +291,11 @@
             c.moveToFirst();
             assertEquals(2, c.getInt(c.getColumnIndex(Members.PLAY_ORDER)));
             assertEquals(memberId, c.getLong(c.getColumnIndex(Members._ID)));
-            assertEquals(Audio2.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+            final String expected2 = Audio2.getInstance().getContentValues(mVolumeName)
+                    .getAsString(Members.DATA);
+            assertEquals(expected2, c.getString(c.getColumnIndex(Members.DATA)));
             assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
             assertEquals(Audio2.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
-            assertEquals(Audio2.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
             assertEquals(Audio2.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
             assertEquals(Audio2.MIME_TYPE, c.getString(c.getColumnIndex(Members.MIME_TYPE)));
             assertEquals(Audio2.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
@@ -333,7 +351,8 @@
                     new long [] {mIdOfAudio1, mIdOfAudio2, mIdOfAudio3}, new int [] {1,2,3});
 
             // delete the middle item
-            mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio2, null);
+            mContentResolver.delete(Media.getContentUri(mVolumeName),
+                    Media._ID + "=" + mIdOfAudio2, null);
 
             // check the remaining items are still in the right order, and the play_order of the
             // last item has been adjusted
@@ -367,7 +386,7 @@
             values.put(Playlists.DATE_ADDED, dateAdded);
             values.put(Playlists.DATE_MODIFIED, dateModified);
             // insert
-            uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+            uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
             assertNotNull(uri);
             c = mContentResolver.query(uri, null, null, null, null);
             c.moveToFirst();
@@ -375,8 +394,7 @@
             c.close();
 
             // insert audio into 2nd playlist
-            Uri members2Uri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                    playlist2Id);
+            Uri members2Uri = Members.getContentUri(mVolumeName, playlist2Id);
             Uri audio2Uri = insertPlaylistItem(members2Uri, mIdOfAudio1, 1);
 
             c = mContentResolver.query(membersUri, null, null, null, null);
@@ -420,8 +438,7 @@
 
             // insert again, then verify that deleting the audio entry cleans up its playlist member
             // entry as well
-            membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
-                    playlistId);
+            membersUri = Members.getContentUri(mVolumeName, playlistId);
             audioUri = insertPlaylistItem(membersUri, mIdOfAudio1, 1);
             assertNotNull(audioUri);
             // Query members of the playlist
@@ -438,7 +455,7 @@
             }
             assertEquals(1, cnt);
             c.close();
-            mContentResolver.delete(Media.EXTERNAL_CONTENT_URI,
+            mContentResolver.delete(Media.getContentUri(mVolumeName),
                     Media._ID + "=" + mIdOfAudio1, null);
             // Query members of the playlist
             c = mContentResolver.query(membersUri,
@@ -456,34 +473,12 @@
 
         } finally {
             // delete the playlists
-            mContentResolver.delete(Playlists.EXTERNAL_CONTENT_URI,
+            mContentResolver.delete(Playlists.getContentUri(mVolumeName),
                     Playlists._ID + "=" + playlistId, null);
             if (playlist2Id >= 0) {
-                mContentResolver.delete(Playlists.EXTERNAL_CONTENT_URI,
+                mContentResolver.delete(Playlists.getContentUri(mVolumeName),
                         Playlists._ID + "=" + playlist2Id, null);
             }
         }
     }
-
-    @Test
-    public void testStoreAudioPlaylistsMembersInternal() {
-        ContentValues values = new ContentValues();
-        values.put(Playlists.NAME, "My favourites");
-        values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
-        long dateAdded = System.currentTimeMillis();
-        values.put(Playlists.DATE_ADDED, dateAdded);
-        long dateModified = System.currentTimeMillis();
-        values.put(Playlists.DATE_MODIFIED, dateModified);
-        // insert
-        Uri uri = mContentResolver.insert(Playlists.INTERNAL_CONTENT_URI, values);
-        assertNotNull(uri);
-
-        try {
-            assertTrue(Pattern.matches("content://media/internal/audio/playlists/\\d+",
-                    uri.toString()));
-        } finally {
-            // delete the playlists
-            assertEquals(1, mContentResolver.delete(uri, null, null));
-        }
-    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
index 56e392c..f9a3372 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
@@ -16,10 +16,11 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.ProviderTestUtils.hash;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import android.content.ContentResolver;
@@ -40,8 +41,6 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
 
-import libcore.io.IoUtils;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -53,8 +52,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -126,11 +123,6 @@
         assertNotNull(c = mContentResolver.query(Downloads.EXTERNAL_CONTENT_URI,
                 null, null, null, null));
         c.close();
-
-        // can not accept any other volume names
-        final String volume = "faveVolume";
-        assertNull(mContentResolver.query(Downloads.getContentUri(volume),
-                null, null, null, null));
     }
 
     @Test
@@ -170,15 +162,12 @@
         assertNotNull(pendingUri);
         mAddedUris.add(pendingUri);
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
                  OutputStream out = session.openOutputStream()) {
                 android.os.FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         final ContentValues updateValues = new ContentValues();
@@ -210,15 +199,12 @@
         assertNotNull(pendingUri);
         mAddedUris.add(pendingUri);
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
                  OutputStream out = session.openOutputStream()) {
                 android.os.FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         assertEquals(1, mContentResolver.delete(publishUri, null, null));
@@ -254,15 +240,12 @@
         assertNotNull(pendingUri);
         mAddedUris.add(pendingUri);
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
                  OutputStream out = session.openOutputStream()) {
                 android.os.FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
         mCountDownLatch.await(NOTIFY_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
 
@@ -341,15 +324,4 @@
         assertNotNull("Failed to scan " + file.getAbsolutePath(), mediaStoreUris[0]);
         return mediaStoreUris[0];
     }
-
-    private static byte[] hash(InputStream in) throws Exception {
-        try (DigestInputStream digestIn = new DigestInputStream(in,
-                MessageDigest.getInstance("SHA-1"));
-                OutputStream out = new FileOutputStream(new File("/dev/null"))) {
-            FileUtils.copy(digestIn, out);
-            return digestIn.getMessageDigest().digest();
-        } finally {
-            IoUtils.closeQuietly(in);
-        }
-    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
index 380ba82..ffc6b49 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -16,8 +16,8 @@
 
 package android.provider.cts;
 
-import static android.provider.cts.ProviderTestUtils.assertExists;
-import static android.provider.cts.ProviderTestUtils.assertNotExists;
+import static android.provider.cts.MediaStoreTest.TAG;
+import static android.provider.cts.ProviderTestUtils.containsId;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -34,108 +34,76 @@
 import android.net.Uri;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Files.FileColumns;
 import android.provider.MediaStore.MediaColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_FilesTest {
     private Context mContext;
     private ContentResolver mResolver;
 
+    private Uri mExternalImages;
+    private Uri mExternalFiles;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mResolver = mContext.getContentResolver();
 
-        cleanup();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        cleanup();
-    }
-
-    void cleanup() {
-        final String testName = getClass().getCanonicalName();
-        mResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
-                "_data LIKE ?1", new String[] {"%" + testName + "%"});
-
-        mResolver.delete(MediaStore.Files.getContentUri("external"),
-                "_data LIKE ?1", new String[] {"%" + testName + "%"});
-
-        File ext = Environment.getExternalStorageDirectory();
-        File[] junk = ext.listFiles(new FilenameFilter() {
-
-            @Override
-            public boolean accept(File dir, String filename) {
-                return filename.contains(testName);
-            }
-        });
-        for (File f: junk) {
-            deleteAll(f);
-        }
-    }
-
-    void deleteAll(File f) {
-        if (f.isDirectory()) {
-            File [] sub = f.listFiles();
-            for (File s: sub) {
-                deleteAll(s);
-            }
-        }
-        f.delete();
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+        mExternalFiles = MediaStore.Files.getContentUri(mVolumeName);
     }
 
     @Test
-    public void testGetContentUri() {
-        String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
-        Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
-
-        // Get the current file count. We will check if this increases after
-        // adding a file to the provider.
-        int fileCount = getFileCount(allFilesUri);
+    public void testGetContentUri() throws Exception {
+        Uri allFilesUri = mExternalFiles;
 
         ContentValues values = new ContentValues();
 
         // Add a path for a file and check that the returned uri appends a
         // path properly.
-        String dataPath = "does_not_really_exist.txt";
+        String dataPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "does_not_really_exist.txt").getAbsolutePath();
         values.put(MediaColumns.DATA, dataPath);
         Uri fileUri = mResolver.insert(allFilesUri, values);
         long fileId = ContentUris.parseId(fileUri);
         assertEquals(fileUri, ContentUris.withAppendedId(allFilesUri, fileId));
 
         // Check that getContentUri with the file id produces the same url
-        Uri rowUri = MediaStore.Files.getContentUri(volumeName, fileId);
+        Uri rowUri = ContentUris.withAppendedId(mExternalFiles, fileId);
         assertEquals(fileUri, rowUri);
 
         // Check that the file count has increased.
-        int newFileCount = getFileCount(allFilesUri);
-        assertEquals(fileCount + 1, newFileCount);
+        assertTrue(containsId(allFilesUri, fileId));
 
         // Check that the path we inserted was stored properly.
         assertStringColumn(fileUri, MediaColumns.DATA, dataPath);
 
         // Update the path and check that the database changed.
-        String updatedPath = "still_does_not_exist.txt";
+        String updatedPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "still_does_not_exist.txt").getAbsolutePath();
         values.put(MediaColumns.DATA, updatedPath);
         assertEquals(1, mResolver.update(fileUri, values, null, null));
         assertStringColumn(fileUri, MediaColumns.DATA, updatedPath);
@@ -146,7 +114,7 @@
 
         // Delete the file and observe that the file count decreased.
         assertEquals(1, mResolver.delete(fileUri, null, null));
-        assertEquals(fileCount, getFileCount(allFilesUri));
+        assertFalse(containsId(allFilesUri, fileId));
 
         // Make sure the deleted file is not returned by the cursor.
         Cursor cursor = mResolver.query(fileUri, null, null, null, null);
@@ -159,7 +127,10 @@
         // insert file and check its parent
         values.clear();
         try {
-            String b = mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC).getCanonicalPath();
+            File stageDir = new File(ProviderTestUtils.stageDir(mVolumeName),
+                    Environment.DIRECTORY_MUSIC);
+            stageDir.mkdirs();
+            String b = stageDir.getAbsolutePath();
             values.put(MediaColumns.DATA, b + "/testing");
             fileUri = mResolver.insert(allFilesUri, values);
             cursor = mResolver.query(fileUri, new String[] { MediaStore.Files.FileColumns.PARENT },
@@ -187,328 +158,113 @@
 
     @Test
     public void testCaseSensitivity() throws IOException {
-        String fileDir = Environment.getExternalStorageDirectory() +
-                "/" + getClass().getCanonicalName();
-        String fileName = fileDir + "/Test.Mp3";
-        writeFile(R.raw.testmp3, fileName);
+        final String name = "Test-" + System.nanoTime() + ".Mp3";
+        final File dir = ProviderTestUtils.stageDir(mVolumeName);
+        final File file = new File(dir, name);
+        final File fileLower = new File(dir, name.toLowerCase());
+        ProviderTestUtils.stageFile(R.raw.testmp3, file);
 
-        String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
-        Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+        Uri allFilesUri = mExternalFiles;
         ContentValues values = new ContentValues();
-        values.put(MediaColumns.DATA, fileDir + "/test.mp3");
+        values.put(MediaColumns.DATA, fileLower.getAbsolutePath());
         Uri fileUri = mResolver.insert(allFilesUri, values);
         try {
             ParcelFileDescriptor pfd = mResolver.openFileDescriptor(fileUri, "r");
             pfd.close();
         } finally {
             mResolver.delete(fileUri, null, null);
-            new File(fileName).delete();
-            new File(fileDir).delete();
         }
     }
 
-    String realPathFor(ParcelFileDescriptor pfd) {
-        File real = new File("/proc/self/fd/" + pfd.getFd());
-        try {
-            return real.getCanonicalPath();
-        } catch (IOException e) {
-            return null;
+    @Test
+    public void testAccessInternal() throws Exception {
+        final Uri internalFiles = MediaStore.Files.getContentUri(MediaStore.VOLUME_INTERNAL);
+
+        for (String valid : new String[] {
+                "/system/media/" + System.nanoTime() + ".ogg",
+        }) {
+            final ContentValues values = new ContentValues();
+            values.put(MediaColumns.DATA, valid);
+
+            final Uri uri = mResolver.insert(internalFiles, values);
+            assertNotNull("Failed to insert " + valid, uri);
+            mResolver.delete(uri, null, null);
+        }
+
+        for (String invalid : new String[] {
+                "/data/media/" + System.nanoTime() + ".jpg",
+                "/data/system/appops.xml",
+                "/data/data/com.android.providers.media/databases/internal.db",
+                new File(Environment.getExternalStorageDirectory(), System.nanoTime() + ".jpg")
+                        .getAbsolutePath(),
+        }) {
+            final ContentValues values = new ContentValues();
+            values.put(MediaColumns.DATA, invalid);
+
+            try {
+                mResolver.insert(internalFiles, values);
+                fail("Able to insert " + invalid);
+            } catch (SecurityException | IllegalArgumentException expected) {
+            }
         }
     }
 
     @Test
     public void testAccess() throws Exception {
-        // clean up from previous run
-        mResolver.delete(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
-                "_data NOT LIKE ?", new String[] { "/system/%" } );
+        final String path = MediaStore.getVolumePath(mVolumeName).getAbsolutePath();
+        final Uri updateUri = ContentUris.withAppendedId(mExternalFiles,
+                ContentUris.parseId(ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages)));
 
-        // insert some dummy starter data into the provider
-        ContentValues values = new ContentValues();
-        values.put(MediaStore.Images.Media.DISPLAY_NAME, "My Bitmap");
-        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
-        values.put(MediaStore.Images.Media.DATA, "/foo/bar/dummy.jpg");
-        Uri uri = mResolver.insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
+        for (String valid : new String[] {
+                path + "/" + System.nanoTime() + ".jpg",
+                path + "/DCIM/" + System.nanoTime() + ".jpg",
+        }) {
+            final ContentValues values = new ContentValues();
+            values.put(MediaColumns.DATA, valid);
 
-        // point _data at directory and try to get an fd for it
-        values = new ContentValues();
-        values.put("_data", "/data/media");
-        mResolver.update(uri, values, null, null);
-        ParcelFileDescriptor pfd = null;
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "r");
-            pfd.close();
-            fail("shouldn't be here");
-        } catch (FileNotFoundException e) {
-            // expected
+            final Uri uri = mResolver.insert(mExternalFiles, values);
+            assertNotNull("Failed to insert " + valid, uri);
+            mResolver.delete(uri, null, null);
+
+            final int count = mResolver.update(updateUri, values, null, null);
+            assertEquals("Failed to update", 1, count);
         }
 
-        // try to create a file in a place we don't have access to
-        values = new ContentValues();
-        values.put("_data", "/data/media/test.dat");
-        mResolver.update(uri, values, null, null);
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "w");
-            pfd.close();
-            fail("shouldn't be here");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-        // read file back
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "r");
-            pfd.close();
-            fail("shouldn't be here");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
+        for (String invalid : new String[] {
+                "/data/media/" + System.nanoTime() + ".jpg",
+                "/data/system/appops.xml",
+                "/data/data/com.android.providers.media/databases/internal.db",
+                path + "/../../../../../data/system/appops.xml",
+        }) {
+            final ContentValues values = new ContentValues();
+            values.put(MediaColumns.DATA, invalid);
 
-        // point _data at media database and read it
-        values = new ContentValues();
-        values.put("_data", "/data/data/com.android.providers.media/databases/internal.db");
-        mResolver.update(uri, values, null, null);
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "r");
-            pfd.close();
-            fail("shouldn't be here");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-
-        // Insert a private file into the database. Since it's private, the media provider won't
-        // be able to open it
-        FileOutputStream fos = mContext.openFileOutput("dummy.dat", Context.MODE_PRIVATE);
-        fos.write(0);
-        fos.close();
-        File path = mContext.getFileStreamPath("dummy.dat");
-        values = new ContentValues();
-        values.put("_data", path.getAbsolutePath());
-
-        mResolver.update(uri, values, null, null);
-        try {
-            pfd = mResolver.openFileDescriptor(uri, "r");
-            pfd.close();
-            fail("shouldn't be here");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-        path.delete();
-
-        File sdfile = null;
-        if (Environment.isExternalStorageEmulated()) {
-            // create file on sdcard and check access via real path
-            String fileDir = Environment.getExternalStorageDirectory() +
-                    "/" + getClass().getCanonicalName() + "/test.mp3";
-            sdfile = new File(fileDir);
-            writeFile(R.raw.testmp3, sdfile.getCanonicalPath());
-            assertExists(sdfile);
-            values = new ContentValues();
-            values.put("_data", sdfile.getCanonicalPath());
-            mResolver.update(uri, values, null, null);
             try {
-                pfd = mResolver.openFileDescriptor(uri, "r");
-
-                // get the real path from the file descriptor (this relies on the media provider
-                // having opened the path via the real path instead of the emulated path).
-                String realPath = realPathFor(pfd);
-                pfd.close();
-                if (realPath.equals(sdfile.getCanonicalPath())) {
-                    // provider did not use real/translated path
-                    sdfile = null;
-                } else {
-                    values = new ContentValues();
-                    values.put("_data", realPath);
-                    mResolver.update(uri, values, null, null);
-
-                    // we shouldn't be able to access this
-                    try {
-                        pfd = mResolver.openFileDescriptor(uri, "r");
-                        fail("shouldn't have fd for " + realPath);
-                    } catch (FileNotFoundException e) {
-                        // expected
-                    } finally {
-                        pfd.close();
-                    }
-                }
-            } catch (FileNotFoundException e) {
-                fail("couldn't open file");
+                mResolver.insert(mExternalFiles, values);
+                fail("Able to insert " + invalid);
+            } catch (SecurityException | IllegalArgumentException expected) {
             }
-        }
 
-        // clean up
-        assertEquals(1, mResolver.delete(uri, null, null));
-        if (sdfile != null) {
-            assertEquals("couldn't delete " + sdfile.getCanonicalPath(), true, sdfile.delete());
-        }
-
-        // test secondary storage if present
-        List<File> allpaths = getSecondaryPackageSpecificPaths(mContext);
-        List<String> trimmedPaths = new ArrayList<String>();
-
-        for (File extpath: allpaths) {
-            assertNotNull("Valid media must be inserted during CTS", extpath);
-            assertEquals("Valid media must be inserted for " + extpath
-                    + " during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(extpath));
-
-            File child = extpath;
-            while (true) {
-                File parent = child.getParentFile();
-                if (parent == null) {
-                    fail("didn't expect to be here");
-                }
-                if (!Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(parent))) {
-                    // we went past the root
-                    String abspath = child.getAbsolutePath();
-                    if (!trimmedPaths.contains(abspath)) {
-                        trimmedPaths.add(abspath);
-                    }
-                    break;
-                }
-                child = parent;
-            }
-        }
-
-        String fileDir = Environment.getExternalStorageDirectory() +
-                "/" + getClass().getCanonicalName() + "-" + SystemClock.elapsedRealtime();
-        String fileName = fileDir + "/TestSecondary.Mp3";
-        writeFile(R.raw.testmp3_2, fileName); // file without album art
-
-
-        // insert temp file
-        values = new ContentValues();
-        values.put(MediaStore.Audio.Media.DATA, fileName);
-        values.put(MediaStore.Audio.Media.ARTIST, "Artist-" + SystemClock.elapsedRealtime());
-        values.put(MediaStore.Audio.Media.ALBUM, "Album-" + SystemClock.elapsedRealtime());
-        values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
-        Uri fileUri = mResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
-        // give media provider some time to realize there's no album art
-        SystemClock.sleep(1000);
-        // get its album id
-        Cursor c = mResolver.query(fileUri, new String[] { MediaStore.Audio.Media.ALBUM_ID},
-                null, null, null);
-        assertTrue(c.moveToFirst());
-        int albumid = c.getInt(0);
-        Uri albumArtUriBase = Uri.parse("content://media/external/audio/albumart");
-        Uri albumArtUri = ContentUris.withAppendedId(albumArtUriBase, albumid);
-        try {
-            pfd = mResolver.openFileDescriptor(albumArtUri, "r");
-            fail("no album art, shouldn't be here. Got: " + realPathFor(pfd));
-        } catch (Exception e) {
-            // expected
-        }
-
-        // replace file with one that has album art
-        writeFile(R.raw.testmp3, fileName); // file with album art
-
-        for (String s: trimmedPaths) {
-            File dir = new File(s + "/foobardir-" + SystemClock.elapsedRealtime());
-            assertNotExists("please remove " + dir.getAbsolutePath()
-                    + " before running", dir.getAbsolutePath());
-            File file = new File(dir, "foobar");
-            values = new ContentValues();
-            values.put(MediaStore.Audio.Media.ALBUM_ID, albumid);
-            values.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
-            mResolver.insert(albumArtUriBase, values);
             try {
-                pfd = mResolver.openFileDescriptor(albumArtUri, "r");
-                fail("shouldn't have fd for album " + albumid + ", got " + realPathFor(pfd));
-            } catch (Exception e) {
-                // expected
-            } finally {
-                pfd.close();
+                mResolver.update(updateUri, values, null, null);
+                fail("Able to update " + invalid);
+            } catch (SecurityException | IllegalArgumentException expected) {
             }
-            assertNotExists(dir.getAbsolutePath() + " was created", dir.getAbsolutePath());
         }
-        mResolver.delete(fileUri, null, null);
-        new File(fileName).delete();
-
-        // try creating files in root
-        for (String s: trimmedPaths) {
-            File dir = new File(s);
-            File file = new File(dir, "foobar.jpg");
-
-            values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
-            fileUri = mResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
-            assertNotNull(fileUri);
-
-            // check that adding the file doesn't cause it to be created
-            assertNotExists(file);
-
-            // check if opening the file for write works
-            try {
-                mResolver.openOutputStream(fileUri).close();
-                fail("shouldn't have been able to create output stream");
-            } catch (SecurityException e) {
-                // expected
-            }
-            // check that deleting the file doesn't cause it to be created
-            mResolver.delete(fileUri, null, null);
-            assertNotExists(file);
-        }
-
-        // try creating files in new subdir
-        for (String s: trimmedPaths) {
-            File dir = new File(s + "/foobardir");
-            File file = new File(dir, "foobar.jpg");
-
-            values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, dir.getAbsolutePath());
-
-            Uri dirUri = mResolver.insert(MediaStore.Files.getContentUri("external"), values);
-            assertNotNull(dirUri);
-
-            values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
-            fileUri = mResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
-            assertNotNull(fileUri);
-
-            // check that adding the file or its folder didn't cause either one to be created
-            assertNotExists(dir);
-            assertNotExists(file);
-
-            // check if opening the file for write works
-            try {
-                mResolver.openOutputStream(fileUri).close();
-                fail("shouldn't have been able to create output stream");
-            } catch (SecurityException e) {
-                // expected
-            }
-            // check that deleting the file or its folder doesn't cause either one to be created
-            mResolver.delete(fileUri, null, null);
-            assertNotExists(dir);
-            assertNotExists(file);
-            mResolver.delete(dirUri, null, null);
-            assertNotExists(dir);
-            assertNotExists(file);
-        }
-    }
-
-    public static List<File> getSecondaryPackageSpecificPaths(Context context) {
-        final List<File> paths = new ArrayList<File>();
-        Collections.addAll(paths, dropFirst(context.getExternalCacheDirs()));
-        Collections.addAll(paths, dropFirst(context.getExternalFilesDirs(null)));
-        Collections.addAll(
-                paths, dropFirst(context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)));
-        Collections.addAll(paths, dropFirst(context.getObbDirs()));
-        return paths;
     }
 
     @Test
     public void testUpdateMediaType() throws Exception {
-        String fileDir = Environment.getExternalStorageDirectory() +
-                "/" + getClass().getCanonicalName();
-        String fileName = fileDir + "/test.mp3";
-        writeFile(R.raw.testmp3, fileName);
+        final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "test" + System.nanoTime() + ".mp3");
+        ProviderTestUtils.stageFile(R.raw.testmp3, file);
 
-        String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
-        Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+        Uri allFilesUri = mExternalFiles;
         ContentValues values = new ContentValues();
-        values.put(MediaColumns.DATA, fileName);
+        values.put(MediaColumns.DATA, file.getAbsolutePath());
         values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
         Uri fileUri = mResolver.insert(allFilesUri, values);
 
-
         // There is special logic in MediaProvider#update() to update paths when a folder was moved
         // or renamed. It only checks whether newValues only has one column but assumes the provided
         // column is _data. We need to guard the case where there is only one column in newValues
@@ -525,28 +281,6 @@
         }
     }
 
-    private static File[] dropFirst(File[] before) {
-        final File[] after = new File[before.length - 1];
-        System.arraycopy(before, 1, after, 0, after.length);
-        return after;
-    }
-
-    private void writeFile(int resid, String path) throws IOException {
-        File out = new File(path);
-        File dir = out.getParentFile();
-        dir.mkdirs();
-        ProviderTestUtils.stageFile(resid, out);
-    }
-
-    private int getFileCount(Uri uri) {
-        Cursor cursor = mResolver.query(uri, null, null, null, null);
-        try {
-            return cursor.getCount();
-        } finally {
-            cursor.close();
-        }
-    }
-
     private void assertStringColumn(Uri fileUri, String columnName, String expectedValue) {
         Cursor cursor = mResolver.query(fileUri, null, null, null, null);
         try {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index b467538..d930560 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -16,9 +16,10 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -30,63 +31,47 @@
 import android.graphics.BitmapFactory;
 import android.media.ExifInterface;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
 import android.platform.test.annotations.Presubmit;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Images.ImageColumns;
 import android.provider.MediaStore.Images.Media;
-import android.provider.MediaStore.Images.Thumbnails;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
+import android.util.Size;
 
 import com.android.compatibility.common.util.FileUtils;
 
-import libcore.io.IoUtils;
-
-import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Images_MediaTest {
     private static final String MIME_TYPE_JPEG = "image/jpeg";
 
-    private static final String TEST_TITLE1 = "test title1";
-
-    private static final String TEST_DESCRIPTION1 = "test description1";
-
-    private static final String TEST_TITLE2 = "test title2";
-
-    private static final String TEST_DESCRIPTION2 = "test description2";
-
-    private static final String TEST_TITLE3 = "test title3";
-
-    private static final String TEST_DESCRIPTION3 = "test description3";
-
-    private static final String LOG_TAG = "MediaStore_Images_MediaTest";
-    
-    private ArrayList<Uri> mRowsAdded;
-
     private Context mContext;
-
     private ContentResolver mContentResolver;
 
-    @After
-    public void tearDown() throws Exception {
-        for (Uri row : mRowsAdded) {
-            mContentResolver.delete(row, null, null);
-        }
+    private Uri mExternalImages;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
     }
 
     @Before
@@ -94,28 +79,31 @@
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
 
-        mRowsAdded = new ArrayList<Uri>();
-
-        File pics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
-        if (!pics.exists()) {
-            Log.i(LOG_TAG, "Nonstandard test-environment: Pictures directory does not exist!");
-            pics.mkdirs();
-            if (!pics.exists()) {
-                Log.i(LOG_TAG, "Couldn't create Pictures directory, some tests may fail!");
-            }
-        }
-
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
     }
 
     @Test
     public void testInsertImageWithImagePath() throws Exception {
-        Cursor c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI, null, null,
+        // TODO: expand test to verify paths from secondary storage devices
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
+        final long unique1 = System.nanoTime();
+        final String TEST_TITLE1 = "Title " + unique1;
+        final String TEST_DESCRIPTION1 = "Description " + unique1;
+
+        final long unique2 = System.nanoTime();
+        final String TEST_TITLE2 = "Title " + unique2;
+        final String TEST_DESCRIPTION2 = "Description " + unique2;
+
+        Cursor c = Media.query(mContentResolver, mExternalImages, null, null,
                 "_id ASC");
         int previousCount = c.getCount();
         c.close();
 
         // insert an image by path
-        File file = mContext.getFileStreamPath("mediaStoreTest1.jpg");
+        File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+                "mediaStoreTest1.jpg");
         String path = file.getAbsolutePath();
         ProviderTestUtils.stageFile(R.raw.scenery, file);
         String stringUrl = null;
@@ -128,10 +116,10 @@
             fail("There is no sdcard attached! " + e.getMessage());
         }
         assertInsertionSuccess(stringUrl);
-        mRowsAdded.add(Uri.parse(stringUrl));
 
         // insert another image by path
-        file = mContext.getFileStreamPath("mediaStoreTest2.jpg");
+        file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+                "mediaStoreTest2.jpg");
         path = file.getAbsolutePath();
         ProviderTestUtils.stageFile(R.raw.scenery, file);
         stringUrl = null;
@@ -144,7 +132,6 @@
             fail("There is no sdcard attached! " + e.getMessage());
         }
         assertInsertionSuccess(stringUrl);
-        mRowsAdded.add(Uri.parse(stringUrl));
 
         // query the newly added image
         c = Media.query(mContentResolver, Uri.parse(stringUrl),
@@ -158,7 +145,7 @@
 
         // query all the images in external db and order them by descending id
         // (make the images added in test case in the first positions)
-        c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI,
+        c = Media.query(mContentResolver, mExternalImages,
                 new String[] { Media.TITLE, Media.DESCRIPTION, Media.MIME_TYPE }, null,
                 "_id DESC");
         assertEquals(previousCount + 2, c.getCount());
@@ -185,6 +172,10 @@
 
     @Test
     public void testInsertImageWithBitmap() throws Exception {
+        final long unique3 = System.nanoTime();
+        final String TEST_TITLE3 = "Title " + unique3;
+        final String TEST_DESCRIPTION3 = "Description " + unique3;
+
         // insert the image by bitmap
         Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
         String stringUrl = null;
@@ -195,7 +186,6 @@
             fail("There is no sdcard attached! " + e.getMessage());
         }
         assertInsertionSuccess(stringUrl);
-        mRowsAdded.add(Uri.parse(stringUrl));
 
         Cursor c = Media.query(mContentResolver, Uri.parse(stringUrl), new String[] { Media.DATA },
                 null, "_id ASC");
@@ -217,26 +207,22 @@
         assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
                 null));
         c.close();
-        assertNotNull(c = mContentResolver.query(Media.getContentUri("external"), null, null, null,
+        assertNotNull(c = mContentResolver.query(Media.getContentUri(mVolumeName), null, null, null,
                 null));
         c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
     }
 
     private void cleanExternalMediaFile(String path) {
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, "_data=?", new String[] { path });
+        mContentResolver.delete(mExternalImages, "_data=?", new String[] { path });
         new File(path).delete();
     }
 
     @Test
     public void testStoreImagesMediaExternal() throws Exception {
-        final String externalPath = Environment.getExternalStorageDirectory().getPath() +
-                "/testimage.jpg";
-        final String externalPath2 = Environment.getExternalStorageDirectory().getPath() +
-                "/testimage1.jpg";
+        final String externalPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "testimage.jpg").getAbsolutePath();
+        final String externalPath2 = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "testimage1.jpg").getAbsolutePath();
 
         // clean up any potential left over entries from a previous aborted run
         cleanExternalMediaFile(externalPath);
@@ -264,7 +250,7 @@
         values.put(Media.DATE_MODIFIED, dateModified);
 
         // insert
-        Uri uri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(mExternalImages, values);
         assertNotNull(uri);
 
         try {
@@ -310,22 +296,16 @@
         }
     }
 
-    private void assertInsertionSuccess(String stringUrl) {
-        assertNotNull(stringUrl);
+    private void assertInsertionSuccess(String stringUrl) throws IOException {
+        final Uri uri = Uri.parse(stringUrl);
+
         // check whether the thumbnails are generated
-        Cursor c = mContentResolver.query(Uri.parse(stringUrl), new String[]{ Media._ID }, null,
-                null, null);
-        assertTrue(c.moveToFirst());
-        long imageId = c.getLong(c.getColumnIndex(Media._ID));
-        c.close();
-        assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
-                Thumbnails.MINI_KIND, null));
-        assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
-                Thumbnails.MICRO_KIND, null));
-        c = mContentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, null,
-                Thumbnails.IMAGE_ID + "=" + imageId, null, null);
-        assertEquals(2, c.getCount());
-        c.close();
+        try (Cursor c = mContentResolver.query(uri, null, null, null)) {
+            assertEquals(1, c.getCount());
+        }
+
+        assertNotNull(mContentResolver.loadThumbnail(uri, new Size(512, 384), null));
+        assertNotNull(mContentResolver.loadThumbnail(uri, new Size(96, 96), null));
     }
 
     /**
@@ -340,19 +320,16 @@
 
         final String displayName = "cts" + System.nanoTime();
         final MediaStore.PendingParams params = new MediaStore.PendingParams(
-                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, displayName, "image/jpeg");
+                mExternalImages, displayName, "image/jpeg");
 
         final Uri pendingUri = MediaStore.createPending(mContext, params);
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.volantis);
                  OutputStream out = session.openOutputStream()) {
                 android.os.FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         final Uri originalUri = MediaStore.setRequireOriginal(publishUri);
@@ -392,19 +369,16 @@
     public void testLocationDeprecated() throws Exception {
         final String displayName = "cts" + System.nanoTime();
         final MediaStore.PendingParams params = new MediaStore.PendingParams(
-                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, displayName, "image/jpeg");
+                mExternalImages, displayName, "image/jpeg");
 
         final Uri pendingUri = MediaStore.createPending(mContext, params);
         final Uri publishUri;
-        final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
-        try {
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
             try (InputStream in = mContext.getResources().openRawResource(R.raw.volantis);
                     OutputStream out = session.openOutputStream()) {
                 android.os.FileUtils.copy(in, out);
             }
             publishUri = session.publish();
-        } finally {
-            IoUtils.closeQuietly(session);
         }
 
         // Verify that location wasn't indexed
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index ee6fbe5..19cba84 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -16,6 +16,7 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
 import static android.provider.cts.ProviderTestUtils.assertExists;
 import static android.provider.cts.ProviderTestUtils.assertNotExists;
 
@@ -30,19 +31,25 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.media.MediaScanner;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ImageDecoder;
 import android.net.Uri;
 import android.os.Environment;
+import android.os.SystemClock;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Images.Media;
 import android.provider.MediaStore.Images.Thumbnails;
 import android.provider.MediaStore.MediaColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Size;
 
 import junit.framework.AssertionFailedError;
 
@@ -50,18 +57,34 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.OutputStream;
 import java.util.ArrayList;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Images_ThumbnailsTest {
     private ArrayList<Uri> mRowsAdded;
 
     private Context mContext;
-
     private ContentResolver mContentResolver;
 
+    private Uri mExternalImages;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    private int mLargestDimension;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     private Uri mRed;
     private Uri mBlue;
 
@@ -83,17 +106,19 @@
         mContentResolver = mContext.getContentResolver();
 
         mRowsAdded = new ArrayList<Uri>();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+
+        final Resources res = mContext.getResources();
+        final Configuration config = res.getConfiguration();
+        mLargestDimension = (int) (Math.max(config.screenWidthDp, config.screenHeightDp)
+                * res.getDisplayMetrics().density);
     }
 
     private void prepareImages() throws Exception {
-        final File red = new File(Environment.getExternalStorageDirectory(), "red.jpg");
-        final File blue = new File(Environment.getExternalStorageDirectory(), "blue.jpg");
-        ProviderTestUtils.stageFile(R.raw.scenery, red);
-        ProviderTestUtils.stageFile(R.raw.scenery, blue);
-        try (MediaScanner scanner = new MediaScanner(mContext, "external")) {
-            mRed = scanner.scanSingleFile(red.getAbsolutePath(), "image/jpeg");
-            mBlue = scanner.scanSingleFile(blue.getAbsolutePath(), "image/jpeg");
-        }
+        mRed = ProviderTestUtils.stageMedia(R.raw.scenery, mExternalImages);
+        mBlue = ProviderTestUtils.stageMedia(R.raw.scenery, mExternalImages);
         mRowsAdded.add(mRed);
         mRowsAdded.add(mBlue);
     }
@@ -106,6 +131,7 @@
 
     @Test
     public void testQueryExternalThumbnails() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
         prepareImages();
 
         Cursor c = Thumbnails.queryMiniThumbnails(mContentResolver,
@@ -114,7 +140,8 @@
         c.close();
 
         // add a thumbnail
-        final File file = mContext.getFileStreamPath("testThumbnails.jpg");
+        final File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+                "testThumbnails.jpg");
         final String path = file.getAbsolutePath();
         ProviderTestUtils.stageFile(R.raw.scenery, file);
         ContentValues values = new ContentValues();
@@ -150,6 +177,9 @@
 
     @Test
     public void testQueryExternalMiniThumbnails() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+        final ContentResolver resolver = mContentResolver;
+
         // insert the image by bitmap
         BitmapFactory.Options opts = new BitmapFactory.Options();
         opts.inTargetDensity = DisplayMetrics.DENSITY_XHIGH;
@@ -174,31 +204,8 @@
         c.close();
 
         assertExists("image file does not exist", imagePath);
-
-        String[] sizeProjection = new String[] { Thumbnails.WIDTH, Thumbnails.HEIGHT };
-        c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
-                sizeProjection);
-        assertEquals(1, c.getCount());
-        assertTrue(c.moveToFirst());
-        assertMostlyEquals(320, c.getInt(c.getColumnIndex(Thumbnails.WIDTH)), 128);
-        assertMostlyEquals(320, c.getInt(c.getColumnIndex(Thumbnails.HEIGHT)), 128);
-        c.close();
-        c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MICRO_KIND,
-                sizeProjection);
-        assertEquals(1, c.getCount());
-        assertTrue(c.moveToFirst());
-        assertMostlyEquals(96, c.getInt(c.getColumnIndex(Thumbnails.WIDTH)), 64);
-        assertMostlyEquals(96, c.getInt(c.getColumnIndex(Thumbnails.HEIGHT)), 64);
-        c.close();
-
-        c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
-                new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
-
-        c.moveToNext();
-        long img = c.getLong(c.getColumnIndex(Thumbnails.IMAGE_ID));
-        assertEquals(imageId, img);
-        String thumbPath = c.getString(c.getColumnIndex(Thumbnails.DATA));
-        assertExists("thumbnail file does not exist", thumbPath);
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // deleting the image from the database also deletes the image file, and the
         // corresponding entry in the thumbnail table, which in turn triggers deletion
@@ -207,14 +214,8 @@
         mRowsAdded.remove(stringUri);
 
         assertNotExists("image file should no longer exist", imagePath);
-
-        Cursor c2 = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
-                new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
-        assertEquals(0, c2.getCount());
-        c2.close();
-
-        assertNotExists("thumbnail file should no longer exist", thumbPath);
-        c.close();
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // insert image, then delete it via the files table
         stringUrl = Media.insertImage(mContentResolver, src, null, null);
@@ -228,30 +229,6 @@
         Uri fileuri = MediaStore.Files.getContentUri("external", imageId);
         mContentResolver.delete(fileuri, null, null);
         assertNotExists("image file should no longer exist", imagePath);
-
-
-        // insert image, then delete its thumbnail
-        stringUrl = Media.insertImage(mContentResolver, src, null, null);
-        c = mContentResolver.query(Uri.parse(stringUrl),
-                new String[]{ Media._ID, Media.DATA}, null, null, null);
-        c.moveToFirst();
-        imageId = c.getLong(c.getColumnIndex(Media._ID));
-        imagePath = c.getString(c.getColumnIndex(Media.DATA));
-        c.close();
-        c2 = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
-                new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
-        c2.moveToFirst();
-        thumbPath = c2.getString(c2.getColumnIndex(Thumbnails.DATA));
-        assertExists("thumbnail file does not exist", thumbPath);
-
-        Uri imguri = Uri.parse(stringUrl);
-        long imgid = ContentUris.parseId(imguri);
-        assertEquals(imgid, imageId);
-        mRowsAdded.add(imguri);
-        mContentResolver.delete(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
-                MediaStore.Images.Thumbnails.IMAGE_ID + "=?", new String[]{ "" + imgid});
-        assertNotExists("thumbnail file should no longer exist", thumbPath);
-        assertExists("image file should still exist", imagePath);
     }
 
     @Test
@@ -260,18 +237,14 @@
         assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri("internal"), null, null,
                 null, null));
         c.close();
-        assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri("external"), null, null,
+        assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri(mVolumeName), null, null,
                 null, null));
         c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Thumbnails.getContentUri(volume), null, null, null,
-                null));
     }
 
     @Test
     public void testStoreImagesMediaExternal() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
         prepareImages();
 
         final String externalImgPath = Environment.getExternalStorageDirectory() +
@@ -317,42 +290,30 @@
 
     @Test
     public void testThumbnailGenerationAndCleanup() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+        final ContentResolver resolver = mContentResolver;
+
         // insert an image
         Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
         Uri uri = Uri.parse(Media.insertImage(mContentResolver, src, "test", "test description"));
+        long imageId = ContentUris.parseId(uri);
 
-        // query its thumbnail
-        Cursor c = mContentResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "image_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sort */
-                );
-        assertTrue("couldn't find thumbnail", c.moveToNext());
-        String path = c.getString(0);
-        c.close();
-        assertExists("thumbnail does not exist", path);
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // delete the source image and check that the thumbnail is gone too
         mContentResolver.delete(uri, null /* where clause */, null /* where args */);
-        assertNotExists("thumbnail still exists after source file delete", path);
+
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // insert again
         uri = Uri.parse(Media.insertImage(mContentResolver, src, "test", "test description"));
+        imageId = ContentUris.parseId(uri);
 
         // query its thumbnail again
-        c = mContentResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "image_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sortOrder */
-                );
-        assertTrue("couldn't find thumbnail", c.moveToNext());
-        path = c.getString(0);
-        c.close();
-        assertExists("thumbnail does not exist", path);
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // update the media type
         ContentValues values = new ContentValues();
@@ -361,23 +322,11 @@
                 1, mContentResolver.update(uri, values, null /* where */, null /* where args */));
 
         // image was marked as regular file in the database, which should have deleted its thumbnail
-
-        // query its thumbnail again
-        c = mContentResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "image_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sort */
-                );
-        if (c != null) {
-            assertFalse("thumbnail entry exists for non-thumbnail file", c.moveToNext());
-            c.close();
-        }
-        assertNotExists("thumbnail remains after source file type change", path);
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+        assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
 
         // check source no longer exists as image
-        c = mContentResolver.query(uri,
+        Cursor c = mContentResolver.query(uri,
                 null /* projection */, null /* where */, null /* where args */, null /* sort */);
         assertFalse("source entry should be gone", c.moveToNext());
         c.close();
@@ -411,6 +360,8 @@
 
     @Test
     public void testThumbnailOrderedQuery() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
         Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
         Uri url[] = new Uri[3];
         try{
@@ -456,4 +407,93 @@
             fail("There is no sdcard attached! " + e.getMessage());
         }
     }
+
+    @Test
+    public void testInsertUpdateDelete() throws Exception {
+        final String displayName = "cts" + System.nanoTime();
+        final MediaStore.PendingParams params = new MediaStore.PendingParams(
+                mExternalImages, displayName, "image/png");
+        final Uri pendingUri = MediaStore.createPending(mContext, params);
+        final Uri finalUri;
+        try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
+            try (OutputStream out = session.openOutputStream()) {
+                writeImage(mLargestDimension, mLargestDimension, Color.RED, out);
+            }
+            finalUri = session.publish();
+        }
+
+        // Directly reading should be larger
+        final Bitmap full = ImageDecoder
+                .decodeBitmap(ImageDecoder.createSource(mContentResolver, finalUri));
+        assertEquals(mLargestDimension, full.getWidth());
+        assertEquals(mLargestDimension, full.getHeight());
+
+        {
+            // Thumbnail should be smaller
+            final Bitmap thumb = mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+            assertTrue(thumb.getWidth() < full.getWidth());
+            assertTrue(thumb.getHeight() < full.getHeight());
+
+            // Thumbnail should match contents
+            assertColorMostlyEquals(Color.RED, thumb.getPixel(16, 16));
+        }
+
+        // Verify legacy APIs still work
+        if (MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) {
+            for (int kind : new int[] {
+                    MediaStore.Images.Thumbnails.MINI_KIND,
+                    MediaStore.Images.Thumbnails.FULL_SCREEN_KIND,
+                    MediaStore.Images.Thumbnails.MICRO_KIND
+            }) {
+                // Thumbnail should be smaller
+                final Bitmap thumb = MediaStore.Images.Thumbnails.getThumbnail(mContentResolver,
+                        ContentUris.parseId(finalUri), kind, null);
+                assertTrue(thumb.getWidth() < full.getWidth());
+                assertTrue(thumb.getHeight() < full.getHeight());
+
+                // Thumbnail should match contents
+                assertColorMostlyEquals(Color.RED, thumb.getPixel(16, 16));
+            }
+        }
+
+        // Edit image contents
+        try (OutputStream out = mContentResolver.openOutputStream(finalUri)) {
+            writeImage(mLargestDimension, mLargestDimension, Color.BLUE, out);
+        }
+
+        // Wait a few moments for events to settle
+        SystemClock.sleep(1000);
+
+        {
+            // Thumbnail should match updated contents
+            final Bitmap thumb = mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+            assertColorMostlyEquals(Color.BLUE, thumb.getPixel(16, 16));
+        }
+
+        // Delete image contents
+        mContentResolver.delete(finalUri, null, null);
+
+        // Thumbnail should no longer exist
+        try {
+            mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+            fail("Funky; we somehow made a thumbnail out of nothing?");
+        } catch (FileNotFoundException expected) {
+        }
+    }
+
+    private static void writeImage(int width, int height, int color, OutputStream out) {
+        final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(bitmap);
+        canvas.drawColor(color);
+        bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
+    }
+
+    /**
+     * Since thumbnails might be bounced through a compression pass, we're okay
+     * if they're mostly equal.
+     */
+    private static void assertColorMostlyEquals(int expected, int actual) {
+        assertEquals(Integer.toHexString(expected & 0xF0F0F0F0),
+                Integer.toHexString(actual & 0xF0F0F0F0));
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
index 1a82b216..612e2b4 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
@@ -16,66 +16,70 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
+import android.provider.MediaStore;
 import android.provider.MediaStore.Video;
 import android.provider.MediaStore.Video.VideoColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
-import java.util.ArrayList;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_VideoTest {
-    private static final String TEST_VIDEO_3GP = "testVideo.3gp";
-
-    private ArrayList<Uri> mRowsAdded;
-
     private Context mContext;
+    private ContentResolver mResolver;
 
-    private ContentResolver mContentResolver;
+    private Uri mExternalVideo;
 
-    @After
-    public void tearDown() throws Exception {
-        for (Uri row : mRowsAdded) {
-            mContentResolver.delete(row, null, null);
-        }
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
     }
 
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
-        mContentResolver = mContext.getContentResolver();
-        mRowsAdded = new ArrayList<Uri>();
+        mResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
     }
 
     @Test
     public void testQuery() throws Exception {
         ContentValues values = new ContentValues();
 
-        final File file = mContext.getFileStreamPath(TEST_VIDEO_3GP);
+        final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "testVideo" + System.nanoTime() + ".3gp");
         final String valueOfData = file.getAbsolutePath();
         ProviderTestUtils.stageFile(R.raw.testvideo, file);
 
         values.put(VideoColumns.DATA, valueOfData);
 
-        Uri newUri = mContentResolver.insert(Video.Media.INTERNAL_CONTENT_URI, values);
-        if (!Video.Media.INTERNAL_CONTENT_URI.equals(newUri)) {
-            mRowsAdded.add(newUri);
-        }
+        Uri newUri = mResolver.insert(mExternalVideo, values);
+        assertNotNull(newUri);
 
-        Cursor c = Video.query(mContentResolver, newUri, new String[] { VideoColumns.DATA });
+        Cursor c = Video.query(mResolver, newUri, new String[] { VideoColumns.DATA });
         assertEquals(1, c.getCount());
         c.moveToFirst();
         assertEquals(valueOfData, c.getString(c.getColumnIndex(VideoColumns.DATA)));
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index c1aae48..c4577b6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -16,12 +16,12 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
 import static android.provider.cts.ProviderTestUtils.assertExists;
 import static android.provider.cts.ProviderTestUtils.assertNotExists;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -30,31 +30,46 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Video.Media;
 import android.provider.MediaStore.Video.VideoColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import com.android.compatibility.common.util.FileUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
 import java.io.IOException;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Video_MediaTest {
     private Context mContext;
     private ContentResolver mContentResolver;
 
+    private Uri mExternalVideo;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mContentResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
     }
 
     @Test
@@ -63,26 +78,22 @@
         assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
                 null));
         c.close();
-        assertNotNull(c = mContentResolver.query(Media.getContentUri("external"), null, null, null,
+        assertNotNull(c = mContentResolver.query(Media.getContentUri(mVolumeName), null, null, null,
                 null));
         c.close();
-
-        // can not accept any other volume names
-        String volume = "fakeVolume";
-        assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
     }
 
     private void cleanExternalMediaFile(String path) {
-        mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, "_data=?", new String[] { path });
+        mContentResolver.delete(mExternalVideo, "_data=?", new String[] { path });
         new File(path).delete();
     }
 
     @Test
     public void testStoreVideoMediaExternal() throws Exception {
-        final String externalVideoPath = Environment.getExternalStorageDirectory().getPath() +
-                 "/video/testvideo.3gp";
-        final String externalVideoPath2 = Environment.getExternalStorageDirectory().getPath() +
-                "/video/testvideo1.3gp";
+        final String externalVideoPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "testvideo.3gp").getAbsolutePath();
+        final String externalVideoPath2 = new File(ProviderTestUtils.stageDir(mVolumeName),
+                "testvideo1.3gp").getAbsolutePath();
 
         // clean up any potential left over entries from a previous aborted run
         cleanExternalMediaFile(externalVideoPath);
@@ -116,7 +127,7 @@
         values.put(Media.DATE_MODIFIED, dateModified);
 
         // insert
-        Uri uri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+        Uri uri = mContentResolver.insert(mExternalVideo, values);
         assertNotNull(uri);
 
         try {
@@ -156,20 +167,10 @@
         // check that the video file is removed when deleting the database entry
         Context context = mContext;
         Uri videoUri = insertVideo(context);
-        File videofile = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+        File videofile = new File(ProviderTestUtils.stageDir(mVolumeName), "testVideo.3gp");
         assertExists(videofile);
         mContentResolver.delete(videoUri, null, null);
         assertNotExists(videofile);
-
-        // insert again, then delete with the "delete data" parameter set to false
-        videoUri = insertVideo(context);
-        assertExists(videofile);
-        Uri.Builder builder = videoUri.buildUpon();
-        builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false");
-        mContentResolver.delete(builder.build(), null, null);
-        assertExists(videofile);
-        videofile.delete();
-
     }
 
     @Test
@@ -185,7 +186,8 @@
     }
 
     private Uri insertVideo(Context context) throws IOException {
-        File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+        final File dir = ProviderTestUtils.stageDir(mVolumeName);
+        final File file = new File(dir, "testVideo.3gp");
         // clean up any potential left over entries from a previous aborted run
         cleanExternalMediaFile(file.getAbsolutePath());
 
@@ -193,6 +195,6 @@
 
         ContentValues values = new ContentValues();
         values.put(VideoColumns.DATA, file.getAbsolutePath());
-        return context.getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
+        return context.getContentResolver().insert(mExternalVideo, values);
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index fbc546f..e265206 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -16,11 +16,12 @@
 
 package android.provider.cts;
 
-import static android.provider.cts.ProviderTestUtils.assertExists;
-import static android.provider.cts.ProviderTestUtils.assertNotExists;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -31,26 +32,36 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.media.MediaMetadataRetriever;
 import android.net.Uri;
-import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemClock;
+import android.provider.MediaStore;
 import android.provider.MediaStore.Files;
 import android.provider.MediaStore.Video.Media;
 import android.provider.MediaStore.Video.Thumbnails;
 import android.provider.MediaStore.Video.VideoColumns;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
+import android.util.Size;
 
 import com.android.compatibility.common.util.MediaUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class MediaStore_Video_ThumbnailsTest {
     private static final String TAG = "MediaStore_Video_ThumbnailsTest";
 
@@ -62,10 +73,23 @@
                 mContext, R.raw.testthumbvideo, "video/");
     }
 
+    private Uri mExternalVideo;
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters
+    public static Iterable<? extends Object> data() {
+        return ProviderTestUtils.getSharedVolumeNames();
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mResolver = mContext.getContentResolver();
+
+        Log.d(TAG, "Using volume " + mVolumeName);
+        mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
     }
 
     @Test
@@ -78,6 +102,8 @@
 
     @Test
     public void testGetThumbnail() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
         // Insert a video into the provider.
         Uri videoUri = insertVideo();
         long videoId = ContentUris.parseId(videoUri);
@@ -85,9 +111,6 @@
         assertEquals(ContentUris.withAppendedId(Media.EXTERNAL_CONTENT_URI, videoId),
                 videoUri);
 
-        // Get the current thumbnail count for future comparison.
-        int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
-
         // Don't run the test if the codec isn't supported.
         if (!hasCodec()) {
             // Calling getThumbnail should not generate a new thumbnail.
@@ -100,31 +123,12 @@
         assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
         assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MICRO_KIND, null));
 
-        // Check that an additional thumbnails have been registered.
-        int count2 = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
-        assertTrue(count2 > count);
-
-        Cursor c = mResolver.query(Thumbnails.EXTERNAL_CONTENT_URI,
-                new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.VIDEO_ID },
-                null, null, null);
-
-        if (c.moveToLast()) {
-            long vid = c.getLong(2);
-            assertEquals(videoId, vid);
-            String path = c.getString(1);
-            assertExists("thumbnail file does not exist", path);
-            long id = c.getLong(0);
-            mResolver.delete(ContentUris.withAppendedId(Thumbnails.EXTERNAL_CONTENT_URI, id),
-                    null, null);
-            assertNotExists("thumbnail file should no longer exist", path);
-        }
-        c.close();
-
         assertEquals(1, mResolver.delete(videoUri, null, null));
     }
 
     @Test
     public void testThumbnailGenerationAndCleanup() throws Exception {
+        if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
 
         if (!hasCodec()) {
             // we don't support video, so no need to run the test
@@ -136,45 +140,20 @@
         Uri uri = insertVideo();
 
         // request thumbnail creation
-        Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
-                Thumbnails.MINI_KIND, null /* options */);
-
-        // query the thumbnail
-        Cursor c = mResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "video_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sort */
-                );
-        assertTrue("couldn't find thumbnail", c.moveToNext());
-        String path = c.getString(0);
-        c.close();
-        assertExists("thumbnail does not exist", path);
+        assertNotNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+                Thumbnails.MINI_KIND, null /* options */));
 
         // delete the source video and check that the thumbnail is gone too
         mResolver.delete(uri, null /* where clause */, null /* where args */);
-        assertNotExists("thumbnail still exists after source file delete", path);
+        assertNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+                Thumbnails.MINI_KIND, null /* options */));
 
         // insert again
         uri = insertVideo();
 
         // request thumbnail creation
-        Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
-                Thumbnails.MINI_KIND, null);
-
-        // query its thumbnail again
-        c = mResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "video_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sort */
-                );
-        assertTrue("couldn't find thumbnail", c.moveToNext());
-        path = c.getString(0);
-        c.close();
-        assertExists("thumbnail does not exist", path);
+        assertNotNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+                Thumbnails.MINI_KIND, null));
 
         // update the media type
         ContentValues values = new ContentValues();
@@ -183,23 +162,11 @@
                 1, mResolver.update(uri, values, null /* where */, null /* where args */));
 
         // video was marked as regular file in the database, which should have deleted its thumbnail
-
-        // query its thumbnail again
-        c = mResolver.query(
-                Thumbnails.EXTERNAL_CONTENT_URI,
-                new String [] {Thumbnails.DATA},
-                "video_id=?",
-                new String[] {uri.getLastPathSegment()},
-                null /* sort */
-                );
-        if (c != null) {
-            assertFalse("thumbnail entry exists for non-thumbnail file", c.moveToNext());
-            c.close();
-        }
-        assertNotExists("thumbnail remains after source file type change", path);
+        assertNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+                Thumbnails.MINI_KIND, null /* options */));
 
         // check source no longer exists as video
-        c = mResolver.query(uri,
+        Cursor c = mResolver.query(uri,
                 null /* projection */, null /* where */, null /* where args */, null /* sort */);
         assertFalse("source entry should be gone", c.moveToNext());
         c.close();
@@ -220,7 +187,8 @@
     }
 
     private Uri insertVideo() throws IOException {
-        File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+        File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+                "testVideo" + System.nanoTime() + ".3gp");
         // clean up any potential left over entries from a previous aborted run
         mResolver.delete(Media.EXTERNAL_CONTENT_URI,
                 "_data=?", new String[] { file.getAbsolutePath() });
@@ -233,12 +201,69 @@
         return mResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
     }
 
-    private int getThumbnailCount(Uri uri) {
-        Cursor cursor = mResolver.query(uri, null, null, null, null);
-        try {
-            return cursor.getCount();
-        } finally {
-            cursor.close();
+    @Test
+    public void testInsertUpdateDelete() throws Exception {
+        final Uri finalUri = ProviderTestUtils.stageMedia(R.raw.testvideo,
+                mExternalVideo, "video/mp4");
+
+        // Directly reading should be larger
+        final Size full;
+        try (MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
+            mmr.setDataSource(mContext, finalUri);
+            full = new Size(
+                    Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_WIDTH)),
+                    Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_HEIGHT)));
         }
+
+        // Thumbnail should be smaller
+        final Bitmap beforeThumb = mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+        assertTrue(beforeThumb.getWidth() < full.getWidth());
+        assertTrue(beforeThumb.getHeight() < full.getHeight());
+        final int beforeColor = beforeThumb.getPixel(16, 16);
+
+        // Verify legacy APIs still work
+        if (MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) {
+            for (int kind : new int[] {
+                    MediaStore.Video.Thumbnails.MINI_KIND,
+                    MediaStore.Video.Thumbnails.FULL_SCREEN_KIND,
+                    MediaStore.Video.Thumbnails.MICRO_KIND
+            }) {
+                assertNotNull(MediaStore.Video.Thumbnails.getThumbnail(mResolver,
+                        ContentUris.parseId(finalUri), kind, null));
+            }
+        }
+
+        // Edit video contents
+        try (InputStream from = mContext.getResources().openRawResource(R.raw.testthumbvideo);
+                OutputStream to = mResolver.openOutputStream(finalUri)) {
+            FileUtils.copy(from, to);
+        }
+
+        // Wait a few moments for events to settle
+        SystemClock.sleep(1000);
+
+        // Thumbnail should match updated contents
+        final Bitmap afterThumb = mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+        final int afterColor = afterThumb.getPixel(16, 16);
+        assertNotColorMostlyEquals(beforeColor, afterColor);
+
+        // Delete video contents
+        mResolver.delete(finalUri, null, null);
+
+        // Thumbnail should no longer exist
+        try {
+            mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+            fail("Funky; we somehow made a thumbnail out of nothing?");
+        } catch (FileNotFoundException expected) {
+        }
+    }
+
+    /**
+     * Since thumbnails might be bounced through a compression pass, we're okay
+     * if they're mostly equal.
+     */
+    private static void assertNotColorMostlyEquals(int expected, int actual) {
+        assertNotEquals(Integer.toHexString(expected & 0xF0F0F0F0),
+                Integer.toHexString(actual & 0xF0F0F0F0));
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index d3e0af1..038291a 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -16,28 +16,46 @@
 
 package android.provider.cts;
 
+import static android.provider.cts.MediaStoreTest.TAG;
+
 import static org.junit.Assert.fail;
 
 import android.app.UiAutomation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
 import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
 import android.support.test.InstrumentationRegistry;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.util.Log;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.util.Arrays;
 import java.util.Objects;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -50,6 +68,17 @@
     private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
             "^Backup Manager currently (enabled|disabled)$");
 
+    static Iterable<String> getSharedVolumeNames() {
+        if (StorageManager.hasIsolatedStorage()) {
+            final Set<String> volumeNames = MediaStore
+                    .getAllVolumeNames(InstrumentationRegistry.getTargetContext());
+            volumeNames.remove(MediaStore.VOLUME_INTERNAL);
+            return volumeNames;
+        } else {
+            return Arrays.asList(MediaStore.VOLUME_EXTERNAL);
+        }
+    }
+
     static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
             throws Exception {
         String mode = setToSmsApp ? "allow" : "default";
@@ -58,8 +87,14 @@
         executeShellCommand(String.format(cmd, packageName, "READ_SMS", mode), uiAutomation);
     }
 
+    static String executeShellCommand(String command) throws IOException {
+        return executeShellCommand(command,
+                InstrumentationRegistry.getInstrumentation().getUiAutomation());
+    }
+
     static String executeShellCommand(String command, UiAutomation uiAutomation)
             throws IOException {
+        Log.v(TAG, "$ " + command);
         ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command.toString());
         BufferedReader br = null;
         try (InputStream in = new FileInputStream(pfd.getFileDescriptor());) {
@@ -67,6 +102,7 @@
             String str = null;
             StringBuilder out = new StringBuilder();
             while ((str = br.readLine()) != null) {
+                Log.v(TAG, "> " + str);
                 out.append(str);
             }
             return out.toString();
@@ -133,76 +169,150 @@
         executeShellCommand("bmgr wipe " + backupTransport + " " + packageName, uiAutomation);
     }
 
-    static String stageInternalFile(int resId, String fileName) throws IOException {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        try (InputStream source = context.getResources().openRawResource(resId);
-                OutputStream target = context.openFileOutput(fileName, Context.MODE_PRIVATE)) {
-            android.os.FileUtils.copy(source, target);
-        }
-        return context.getFileStreamPath(fileName).getAbsolutePath();
+    static File stageDir(String volumeName) throws IOException {
+        return Environment.buildPath(MediaStore.getVolumePath(volumeName), "Android", "media",
+                "android.provider.cts");
     }
 
     static void stageFile(int resId, File file) throws IOException {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        try (InputStream source = context.getResources().openRawResource(resId);
-                OutputStream target = new FileOutputStream(file)) {
-            android.os.FileUtils.copy(source, target);
+        // The caller may be trying to stage into a location only available to
+        // the shell user, so we need to perform the entire copy as the shell
+        if (FileUtils.contains(Environment.getStorageDirectory(), file)) {
+            executeShellCommand("mkdir -p " + file.getParent());
+
+            final Context context = InstrumentationRegistry.getTargetContext();
+            try (AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId)) {
+                final File source = ParcelFileDescriptor.getFile(afd.getFileDescriptor());
+                final long skip = afd.getStartOffset();
+                final long count = afd.getLength();
+
+                executeShellCommand(String.format("dd bs=1 if=%s skip=%d count=%d of=%s",
+                        source.getAbsolutePath(), skip, count, file.getAbsolutePath()));
+
+                // Force sync to try updating other views
+                executeShellCommand("sync");
+            }
+        } else {
+            final File dir = file.getParentFile();
+            dir.mkdirs();
+            if (!dir.exists()) {
+                throw new FileNotFoundException("Failed to create parent for " + file);
+            }
+            final Context context = InstrumentationRegistry.getTargetContext();
+            try (InputStream source = context.getResources().openRawResource(resId);
+                    OutputStream target = new FileOutputStream(file)) {
+                FileUtils.copy(source, target);
+            }
         }
     }
 
     static Uri stageMedia(int resId, Uri collectionUri) throws IOException {
+        return stageMedia(resId, collectionUri, "image/png");
+    }
+
+    static Uri stageMedia(int resId, Uri collectionUri, String mimeType) throws IOException {
         final Context context = InstrumentationRegistry.getTargetContext();
         final String displayName = "cts" + System.nanoTime();
         final MediaStore.PendingParams params = new MediaStore.PendingParams(
-                collectionUri, displayName, "image/png");
+                collectionUri, displayName, mimeType);
         final Uri pendingUri = MediaStore.createPending(context, params);
         try (MediaStore.PendingSession session = MediaStore.openPending(context, pendingUri)) {
             try (InputStream source = context.getResources().openRawResource(resId);
                     OutputStream target = session.openOutputStream()) {
-                android.os.FileUtils.copy(source, target);
+                FileUtils.copy(source, target);
             }
             return session.publish();
         }
     }
 
-    public static void assertExists(String path) throws ErrnoException {
+    static Uri scanFile(File file) throws Exception {
+        final ContentResolver resolver = InstrumentationRegistry.getTargetContext()
+                .getContentResolver();
+        try (ContentProviderClient cpc = resolver
+                .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+            final Bundle in = new Bundle();
+            in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
+            in.putBoolean(Intent.EXTRA_LOCAL_ONLY, true);
+            final Bundle out = cpc.call(MediaStore.AUTHORITY, MediaStore.SCAN_FILE_CALL, null, in);
+            return out.getParcelable(Intent.EXTRA_STREAM);
+        }
+    }
+
+    static void scanVolume(File file) throws Exception {
+        final ContentResolver resolver = InstrumentationRegistry.getTargetContext()
+                .getContentResolver();
+        try (ContentProviderClient cpc = resolver
+                .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+            final Bundle in = new Bundle();
+            in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
+            in.putBoolean(Intent.EXTRA_LOCAL_ONLY, true);
+            cpc.call(MediaStore.AUTHORITY, MediaStore.SCAN_VOLUME_CALL, null, in);
+        }
+    }
+
+    public static byte[] hash(InputStream in) throws Exception {
+        try (DigestInputStream digestIn = new DigestInputStream(in,
+                MessageDigest.getInstance("SHA-1"));
+                OutputStream out = new FileOutputStream(new File("/dev/null"))) {
+            FileUtils.copy(digestIn, out);
+            return digestIn.getMessageDigest().digest();
+        }
+    }
+
+    public static void assertExists(String path) throws IOException {
         assertExists(null, path);
     }
 
-    public static void assertExists(File file) throws ErrnoException {
+    public static void assertExists(File file) throws IOException {
         assertExists(null, file.getAbsolutePath());
     }
 
-    public static void assertExists(String msg, String path) throws ErrnoException {
-        try {
-            Os.access(path, OsConstants.F_OK);
-        } catch (ErrnoException e) {
-            if (e.errno == OsConstants.ENOENT) {
-                fail(msg);
-            } else {
-                throw e;
-            }
+    public static void assertExists(String msg, String path) throws IOException {
+        if (!access(path)) {
+            fail(msg);
         }
     }
 
-    public static void assertNotExists(String path) throws ErrnoException {
+    public static void assertNotExists(String path) throws IOException {
         assertNotExists(null, path);
     }
 
-    public static void assertNotExists(File file) throws ErrnoException {
+    public static void assertNotExists(File file) throws IOException {
         assertNotExists(null, file.getAbsolutePath());
     }
 
-    public static void assertNotExists(String msg, String path) throws ErrnoException {
-        try {
-            Os.access(path, OsConstants.F_OK);
+    public static void assertNotExists(String msg, String path) throws IOException {
+        if (access(path)) {
             fail(msg);
-        } catch (ErrnoException e) {
-            if (e.errno == OsConstants.ENOENT) {
-                return;
-            } else {
-                throw e;
+        }
+    }
+
+    private static boolean access(String path) throws IOException {
+        // The caller may be trying to stage into a location only available to
+        // the shell user, so we need to perform the entire copy as the shell
+        if (FileUtils.contains(Environment.getStorageDirectory(), new File(path))) {
+            return executeShellCommand("ls -la " + path).contains(path);
+        } else {
+            try {
+                Os.access(path, OsConstants.F_OK);
+                return true;
+            } catch (ErrnoException e) {
+                if (e.errno == OsConstants.ENOENT) {
+                    return false;
+                } else {
+                    throw new IOException(e.getMessage());
+                }
             }
         }
     }
+
+    public static boolean containsId(Uri uri, long id) {
+        try (Cursor c = InstrumentationRegistry.getTargetContext().getContentResolver().query(uri,
+                new String[] { MediaColumns._ID }, null, null)) {
+            while (c.moveToNext()) {
+                if (c.getLong(0) == id) return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 01be317..917b1bc 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -98,6 +98,15 @@
     }
 
     @Test
+    public void nfcPanel_correctPackage() {
+        launchNfcPanel();
+
+        String currentPackage = mDevice.getCurrentPackageName();
+
+        assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+    }
+
+    @Test
     public void internetPanel_correctTitle() {
         launchInternetPanel();
 
@@ -116,6 +125,15 @@
     }
 
     @Test
+    public void nfcPanel_correctTitle() {
+        launchNfcPanel();
+
+        final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+
+        assertThat(titleView.getText()).isEqualTo("NFC");
+    }
+
+    @Test
     public void internetPanel_doneClosesPanel() {
         // Launch panel
         launchInternetPanel();
@@ -148,6 +166,22 @@
     }
 
     @Test
+    public void nfcPanel_doneClosesPanel() {
+        // Launch panel
+        launchNfcPanel();
+        String currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+
+        // Click the done button
+        mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+        mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
+
+        // Assert that we have left the panel
+        currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+    }
+
+    @Test
     public void internetPanel_seeMoreButton_launchesIntoSettings() {
         // Launch panel
         launchInternetPanel();
@@ -183,6 +217,24 @@
         assertThat(titleView).isNull();
     }
 
+    @Test
+    public void nfcPanel_seeMoreButton_launchesIntoSettings() {
+        // Launch panel
+        launchNfcPanel();
+        String currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+
+        // Click the see more button
+        mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
+        mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+
+        // Assert that we're still in Settings, on a different page.
+        currentPackage = mDevice.getCurrentPackageName();
+        assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+        UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+        assertThat(titleView).isNull();
+    }
+
     private void launchVolumePanel() {
         launchPanel(Settings.Panel.ACTION_VOLUME);
     }
@@ -191,6 +243,10 @@
         launchPanel(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
     }
 
+    private void launchNfcPanel() {
+        launchPanel(Settings.Panel.ACTION_NFC);
+    }
+
     private void launchPanel(String action) {
         // Start from the home screen
         mDevice.pressHome();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
index c0ff4c0..be9d1d2 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
@@ -32,7 +32,7 @@
         List<ResolveInfo> resolveInfoList = getContext()
                 .getPackageManager().queryIntentActivities(intent, 0);
         assertNotNull("Missing ResolveInfo", resolveInfoList);
-        assertTrue("No ResolveInfo found for " + intent.toInsecureString(),
+        assertTrue("No ResolveInfo found for " + intent.toString(),
                 resolveInfoList.size() > 0);
     }
 
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
index c19e571..7b3a93a 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
@@ -59,7 +59,7 @@
         long [] contactIds = setupThreeContacts();
 
         // Setup: create query with first and last name reversed.
-        Uri uri = AggregationSuggestions.builder()
+        Uri uri = new AggregationSuggestions.Builder()
                 .addNameParameter("last1 first1")
                 .build();
 
@@ -81,7 +81,7 @@
         long [] contactIds = setupThreeContacts();
 
         // Setup: create query with first and last name in same order as display name.
-        Uri uri = AggregationSuggestions.builder()
+        Uri uri = new AggregationSuggestions.Builder()
                 .addNameParameter("first1 last1")
                 .build();
 
@@ -102,7 +102,7 @@
         setupThreeContacts();
 
         // Setup: query with name that is completely different than all the contacts.
-        Uri uri = AggregationSuggestions.builder()
+        Uri uri = new AggregationSuggestions.Builder()
                 .addNameParameter("unmatched name")
                 .build();
 
@@ -118,7 +118,7 @@
         long [] contactIds = setupThreeContacts();
 
         // Setup: query with two names. The first name is completely unlike all the contacts.
-        Uri uri = AggregationSuggestions.builder()
+        Uri uri = new AggregationSuggestions.Builder()
                 .addNameParameter("unmatched name")
                 .addNameParameter("first2 last2")
                 .build();
@@ -139,7 +139,7 @@
         long [] contactIds = setupThreeContacts();
 
         // Setup: query with two names. The second name is completely unlike all the contacts.
-        Uri uri = AggregationSuggestions.builder()
+        Uri uri = new AggregationSuggestions.Builder()
                 .addNameParameter("first2 last2")
                 .addNameParameter("unmatched name")
                 .build();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
index 5e27e21..89960cc 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
@@ -50,12 +50,10 @@
                 testCallback(intent);
             }
 
-            @Override
             public void startActivityAsUser(Intent intent, UserHandle user) {
                 testCallback(intent);
             }
 
-            @Override
             public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
                 testCallback(intent);
             }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java
deleted file mode 100644
index 24cc122..0000000
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 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.provider.cts.contacts;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.provider.ContactsContract.StreamItemPhotos;
-import android.provider.ContactsContract.StreamItems;
-import android.provider.cts.PhotoUtil;
-import android.test.AndroidTestCase;
-
-public class ContactsContract_StreamItemPhotosTest extends AndroidTestCase {
-
-    private ContentResolver mResolver;
-
-    private Uri mStreamItemUri;
-
-    private long mStreamItemId;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mResolver = mContext.getContentResolver();
-
-        long rawContactId = ContactsContract_StreamItemsTest.insertRawContact(mResolver);
-        mStreamItemUri = ContactsContract_StreamItemsTest.insertViaContentDirectoryUri(mResolver,
-                rawContactId);
-        mStreamItemId = ContentUris.parseId(mStreamItemUri);
-        assertTrue(mStreamItemId != -1);
-    }
-
-    public void testContentDirectoryUri() {
-        byte[] photoData = PhotoUtil.getTestPhotoData(mContext);
-        ContentValues values = new ContentValues();
-        values.put(StreamItemPhotos.SORT_INDEX, 1);
-        values.put(StreamItemPhotos.PHOTO, photoData);
-
-        Uri insertUri = Uri.withAppendedPath(
-                ContentUris.withAppendedId(StreamItems.CONTENT_URI, mStreamItemId),
-                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
-        Uri uri = mResolver.insert(insertUri, values);
-        long photoId = ContentUris.parseId(uri);
-        assertTrue(photoId != -1);
-        assertEquals(Uri.withAppendedPath(insertUri, Long.toString(photoId)), uri);
-    }
-
-    public void testContentPhotoUri() {
-        byte[] photoData = PhotoUtil.getTestPhotoData(mContext);
-        ContentValues values = new ContentValues();
-        values.put(StreamItemPhotos.STREAM_ITEM_ID, mStreamItemId);
-        values.put(StreamItemPhotos.SORT_INDEX, 1);
-        values.put(StreamItemPhotos.PHOTO, photoData);
-
-        Uri uri = mResolver.insert(StreamItems.CONTENT_PHOTO_URI, values);
-        long photoId = ContentUris.parseId(uri);
-        assertTrue(photoId != -1);
-        assertEquals(Uri.withAppendedPath(StreamItems.CONTENT_PHOTO_URI,
-                Long.toString(photoId)), uri);
-    }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java
deleted file mode 100644
index a69b97c..0000000
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2012 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.provider.cts.contacts;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StreamItems;
-import android.test.AndroidTestCase;
-
-import java.util.ArrayList;
-
-public class ContactsContract_StreamItemsTest extends AndroidTestCase {
-
-    private static final String ACCOUNT_TYPE = "com.android.cts";
-    private static final String ACCOUNT_NAME = "ContactsContract_StreamItemsTest";
-
-    private static final String INSERT_TEXT = "Wrote a test for the StreamItems class";
-    private static final long INSERT_TIMESTAMP = 3007;
-    private static final String INSERT_COMMENTS = "1337 people reshared this";
-
-    private static final String UPDATE_TEXT = "Wrote more tests for the StreamItems class";
-    private static final long UPDATE_TIMESTAMP = 8008;
-    private static final String UPDATE_COMMENTS = "3007 people reshared this";
-
-    private ContentResolver mResolver;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mResolver = mContext.getContentResolver();
-    }
-
-    public void testContentDirectoryUri() throws Exception {
-        long rawContactId = insertRawContact(mResolver);
-        Uri streamItemUri = insertViaContentDirectoryUri(mResolver, rawContactId);
-        long streamItemId = ContentUris.parseId(streamItemUri);
-        assertTrue(streamItemId != -1);
-
-        // Check that the provider returns the stream id in it's URI.
-        assertEquals(streamItemUri,
-                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId).buildUpon()
-                        .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY)
-                        .appendPath(Long.toString(streamItemId))
-                        .build());
-
-        // Check that the provider stored what we put into it.
-        assertInsertedItem(streamItemUri);
-
-        // Update the stream item.
-        ContentValues values = new ContentValues();
-        values.put(Data.RAW_CONTACT_ID, rawContactId);
-        values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
-        values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
-        values.put(StreamItems.TEXT, UPDATE_TEXT);
-        values.put(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP);
-        values.put(StreamItems.COMMENTS, UPDATE_COMMENTS);
-
-        assertEquals(1, mResolver.update(streamItemUri, values, null, null));
-        assertUpdatedItem(streamItemUri);
-    }
-
-    static long insertRawContact(ContentResolver resolver) {
-        // Create a contact to attach the stream item to it.
-        ContentValues values = new ContentValues();
-        values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
-        values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
-
-        Uri contactUri = resolver.insert(RawContacts.CONTENT_URI, values);
-        long rawContactId = ContentUris.parseId(contactUri);
-        assertTrue(rawContactId != -1);
-        return rawContactId;
-    }
-
-    static Uri insertViaContentDirectoryUri(ContentResolver resolver, long rawContactId) {
-        // Attach a stream item to the contact.
-        ContentValues values = new ContentValues();
-        values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
-        values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
-        values.put(StreamItems.TEXT, INSERT_TEXT);
-        values.put(StreamItems.TIMESTAMP, INSERT_TIMESTAMP);
-        values.put(StreamItems.COMMENTS, INSERT_COMMENTS);
-
-        Uri contactStreamUri = Uri.withAppendedPath(
-                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
-                RawContacts.StreamItems.CONTENT_DIRECTORY);
-        return resolver.insert(contactStreamUri, values);
-    }
-
-    public void testContentUri() throws Exception {
-        // Create a contact with one stream item in it.
-        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
-
-        ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
-                .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
-                .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
-                .build());
-
-        ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_URI)
-                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
-                .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
-                .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
-                .withValue(StreamItems.TEXT, INSERT_TEXT)
-                .withValue(StreamItems.TIMESTAMP, INSERT_TIMESTAMP)
-                .withValue(StreamItems.COMMENTS, INSERT_COMMENTS)
-                .build());
-
-        ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
-        long rawContactId = ContentUris.parseId(results[0].uri);
-        assertTrue(rawContactId != -1);
-
-        Uri streamItemUri = results[1].uri;
-        long streamItemId = ContentUris.parseId(streamItemUri);
-        assertTrue(streamItemId != -1);
-
-        // Check that the provider returns the stream id in it's URI.
-        assertEquals(streamItemUri,
-                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId));
-
-        // Check that the provider stored what we put into it.
-        assertInsertedItem(streamItemUri);
-
-        // Update the stream item.
-        ops.clear();
-        ops.add(ContentProviderOperation.newUpdate(streamItemUri)
-                .withValue(Data.RAW_CONTACT_ID, rawContactId)
-                .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
-                .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
-                .withValue(StreamItems.TEXT, UPDATE_TEXT)
-                .withValue(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP)
-                .withValue(StreamItems.COMMENTS, UPDATE_COMMENTS)
-                .build());
-
-        results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
-        assertEquals(Integer.valueOf(1), results[0].count);
-        assertUpdatedItem(streamItemUri);
-    }
-
-    private void assertInsertedItem(Uri itemUri) {
-        assertStreamItem(itemUri, INSERT_TEXT, INSERT_TIMESTAMP, INSERT_COMMENTS);
-    }
-
-    private void assertUpdatedItem(Uri itemUri) {
-        assertStreamItem(itemUri, UPDATE_TEXT, UPDATE_TIMESTAMP, UPDATE_COMMENTS);
-    }
-
-    private void assertStreamItem(Uri uri, String text, long timestamp, String comments) {
-        Cursor cursor = mResolver.query(uri, null, null, null, null);
-        try {
-            assertTrue(cursor.moveToFirst());
-            assertEquals(text, cursor.getString(
-                    cursor.getColumnIndexOrThrow(StreamItems.TEXT)));
-            assertEquals(timestamp, cursor.getLong(
-                    cursor.getColumnIndexOrThrow(StreamItems.TIMESTAMP)));
-            assertEquals(comments, cursor.getString(
-                    cursor.getColumnIndexOrThrow(StreamItems.COMMENTS)));
-        } finally {
-            cursor.close();
-        }
-    }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
index a923584..15b228c 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
@@ -16,9 +16,6 @@
 
 package android.provider.cts.contacts;
 
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
 import android.content.ContentProviderClient;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -32,22 +29,22 @@
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 
+import junit.framework.Assert;
+import junit.framework.ComparisonFailure;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import junit.framework.Assert;
-import junit.framework.ComparisonFailure;
-
 /**
  * A test data builder for ContactsContract tests.
  */
 public class ContactsContract_TestDataBuilder {
     private ContentProviderClient mProvider;
-    private ArrayList<Builder<?>> mCreatedRows = Lists.newArrayList();
-    private HashSet<Builder<?>> mLoadedRows = Sets.newHashSet();
+    private ArrayList<Builder<?>> mCreatedRows = new ArrayList<>();
+    private HashSet<Builder<?>> mLoadedRows = new HashSet<>();
 
     private interface IdQuery {
         String[] COLUMNS = new String[] {
@@ -170,7 +167,7 @@
             mLoadedRows.add(this);
 
             StringBuilder selection = new StringBuilder();
-            ArrayList<String> selectionArgs = Lists.newArrayList();
+            ArrayList<String> selectionArgs = new ArrayList<>();
             Set<Map.Entry<String, Object>> entries = mValues.valueSet();
             for (Map.Entry<String, Object> entry : entries) {
                 String column = entry.getKey();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
index ced09d6..4f82a49 100755
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
@@ -16,26 +16,18 @@
 
 package android.provider.cts.contacts;
 
-import static android.provider.cts.contacts.DatabaseAsserts.ContactIdPair;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.content.ContentResolver;
 import android.os.SystemClock;
-import android.provider.cts.contacts.CommonDatabaseUtils;
-import android.provider.cts.contacts.ContactUtil;
-import android.provider.cts.contacts.DataUtil;
-import android.provider.cts.contacts.DatabaseAsserts;
-import android.provider.cts.contacts.DeletedContactUtil;
-import android.provider.cts.contacts.RawContactUtil;
+import android.provider.cts.contacts.DatabaseAsserts.ContactIdPair;
 import android.provider.cts.contacts.account.StaticAccountAuthenticator;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
-import com.google.android.collect.Lists;
-
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 @MediumTest
 public class ContactsProvider2_AccountRemovalTest extends AndroidTestCase {
@@ -102,7 +94,7 @@
      */
     public void testAccountRemovalWithMergedContact_deletesContacts() {
         mAccountManager.addAccountExplicitly(ACCT_1, null, null);
-        ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
+        List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
         mAccountManager.removeAccount(ACCT_1, null, null);
         assertContactsDeletedEventually(System.currentTimeMillis(), idList);
     }
@@ -114,7 +106,7 @@
     public void testAccountRemovalWithMergedContact_doesNotDeleteContactAndTimestampUpdated() {
         mAccountManager.addAccountExplicitly(ACCT_1, null, null);
         mAccountManager.addAccountExplicitly(ACCT_2, null, null);
-        ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_2);
+        List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_2);
         long contactId = idList.get(0).mContactId;
 
         long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
@@ -131,13 +123,13 @@
 
     public void testAccountRemovalWithMergedContact_hasDeleteLogsForContacts() {
         mAccountManager.addAccountExplicitly(ACCT_1, null, null);
-        ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
+        List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
         long start = System.currentTimeMillis();
         mAccountManager.removeAccount(ACCT_1, null, null);
         assertContactsInDeleteLogEventually(start, idList);
     }
 
-    private ArrayList<ContactIdPair> createAndAssertMergedContact(Account acct, Account acct2) {
+    private List<ContactIdPair> createAndAssertMergedContact(Account acct, Account acct2) {
         ContactIdPair ids1 = DatabaseAsserts.assertAndCreateContactWithName(mResolver, acct,
                 "merge me");
         DataUtil.insertPhoneNumber(mResolver, ids1.mRawContactId, "555-5555");
@@ -154,7 +146,7 @@
         ids1.mContactId = mergedContactId;
         ids2.mContactId = mergedContactId;
 
-        return Lists.newArrayList(ids1, ids2);
+        return Arrays.asList(ids1, ids2);
     }
 
     private long assertMerged(long start, long rawContactId, long rawContactId2) {
@@ -178,7 +170,7 @@
         return NOT_MERGED;
     }
 
-    private void assertContactsInDeleteLogEventually(long start, ArrayList<ContactIdPair> idList) {
+    private void assertContactsInDeleteLogEventually(long start, List<ContactIdPair> idList) {
         // Can not use newArrayList() because the version that accepts size is missing.
         ArrayList<ContactIdPair> remaining = new ArrayList<ContactIdPair>(idList.size());
         remaining.addAll(idList);
@@ -189,7 +181,7 @@
                     " are not in delete log after account removal.");
 
             // Need a second list to remove since we can't remove from the list while iterating.
-            ArrayList<ContactIdPair> toBeRemoved = Lists.newArrayList();
+            ArrayList<ContactIdPair> toBeRemoved = new ArrayList<>();
             for (ContactIdPair ids : remaining) {
                 long deletedTime = DeletedContactUtil.queryDeletedTimestampForContactId(mResolver,
                         ids.mContactId);
@@ -209,7 +201,7 @@
      * Polls every so often to see if all contacts have been deleted.  If not deleted in the
      * pre-defined threshold, fails.
      */
-    private void assertContactsDeletedEventually(long start, ArrayList<ContactIdPair> idList) {
+    private void assertContactsDeletedEventually(long start, List<ContactIdPair> idList) {
         // Can not use newArrayList() because the version that accepts size is missing.
         ArrayList<ContactIdPair> remaining = new ArrayList<ContactIdPair>(idList.size());
         remaining.addAll(idList);
@@ -219,7 +211,7 @@
             assertWithinTimeoutLimit(start, "Contacts have not been deleted after account"
                     + " removal.");
 
-            ArrayList<ContactIdPair> toBeRemoved = Lists.newArrayList();
+            ArrayList<ContactIdPair> toBeRemoved = new ArrayList<>();
             for (ContactIdPair ids : remaining) {
                 if (!RawContactUtil.rawContactExistsById(mResolver, ids.mRawContactId)) {
                     toBeRemoved.add(ids);
@@ -244,7 +236,7 @@
      * Creates a given number of contacts for an account.
      */
     private ArrayList<ContactIdPair> createContacts(Account account, int numContacts) {
-        ArrayList<ContactIdPair> accountIds = Lists.newArrayList();
+        ArrayList<ContactIdPair> accountIds = new ArrayList<>();
         for (int i = 0; i < numContacts; i++) {
             accountIds.add(DatabaseAsserts.assertAndCreateContact(mResolver, account));
         }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
index 91f53d4..3b4854b 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
@@ -16,14 +16,10 @@
 
 package android.provider.cts.contacts;
 
-import android.content.Context;
 import android.provider.Contacts;
 import android.provider.Contacts.ContactMethods;
 import android.test.AndroidTestCase;
 
-import com.android.internal.R;
-
-
 public class Contacts_ContactMethodsTest extends AndroidTestCase {
     public void testAddPostalLocation() {
     }
@@ -57,49 +53,8 @@
                 ContactMethods.TYPE_CUSTOM, label).toString();
         assertEquals(label, display);
 
-        CharSequence[] labels = getContext().getResources().getTextArray(
-                com.android.internal.R.array.emailAddressTypes);
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
-                ContactMethods.TYPE_HOME, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_HOME - 1], display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
-                ContactMethods.TYPE_OTHER, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_OTHER - 1], display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
-                ContactMethods.TYPE_WORK, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_WORK - 1], display);
-
-        String untitled = getContext().getString(R.string.untitled);
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_IM,
-                ContactMethods.TYPE_CUSTOM, label).toString();
-        assertEquals(untitled, display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_ORGANIZATION,
-                ContactMethods.TYPE_CUSTOM, label).toString();
-        assertEquals(untitled, display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_PHONE,
-                ContactMethods.TYPE_CUSTOM, label).toString();
-        assertEquals(untitled, display);
-
         display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
                 ContactMethods.TYPE_CUSTOM, label).toString();
         assertEquals(label, display);
-
-        labels = getContext().getResources().getTextArray(
-                com.android.internal.R.array.postalAddressTypes);
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
-                ContactMethods.TYPE_HOME, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_HOME - 1], display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
-                ContactMethods.TYPE_OTHER, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_OTHER - 1], display);
-
-        display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
-                ContactMethods.TYPE_WORK, label).toString();
-        assertEquals(labels[ContactMethods.TYPE_WORK - 1], display);
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
index 814c845..37e3266 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
@@ -16,7 +16,6 @@
 
 package android.provider.cts.contacts;
 
-import android.content.Context;
 import android.provider.Contacts.Organizations;
 import android.test.AndroidTestCase;
 
@@ -26,15 +25,5 @@
         String display = Organizations.getDisplayLabel(getContext(),
                 Organizations.TYPE_CUSTOM, label).toString();
         assertEquals(label, display);
-
-        CharSequence[] labels = getContext().getResources().getTextArray(
-                com.android.internal.R.array.organizationTypes);
-        display = Organizations.getDisplayLabel(getContext(),
-                Organizations.TYPE_OTHER, label).toString();
-        assertEquals(labels[Organizations.TYPE_OTHER - 1], display);
-
-        display = Organizations.getDisplayLabel(getContext(),
-                Organizations.TYPE_WORK, label).toString();
-        assertEquals(labels[Organizations.TYPE_WORK - 1], display);
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
index 363ba61..ab296a3 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
@@ -26,36 +26,6 @@
         String display = Phones.getDisplayLabel(getContext(),
                 Phones.TYPE_CUSTOM, label).toString();
         assertEquals(label, display);
-
-        CharSequence[] labels = getContext().getResources().getTextArray(
-                com.android.internal.R.array.phoneTypes);
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_HOME, label).toString();
-        assertEquals(labels[Phones.TYPE_HOME - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_MOBILE, label).toString();
-        assertEquals(labels[Phones.TYPE_MOBILE - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_WORK, label).toString();
-        assertEquals(labels[Phones.TYPE_WORK - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_FAX_WORK, label).toString();
-        assertEquals(labels[Phones.TYPE_FAX_WORK - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_FAX_HOME, label).toString();
-        assertEquals(labels[Phones.TYPE_FAX_HOME - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_PAGER, label).toString();
-        assertEquals(labels[Phones.TYPE_PAGER - 1], display);
-
-        display = Phones.getDisplayLabel(getContext(),
-                Phones.TYPE_OTHER, label).toString();
-        assertEquals(labels[Phones.TYPE_OTHER - 1], display);
     }
 
     public void testGetDisplayLabelCharSequenceArray() {
diff --git a/tests/tests/provider/src/libcore/util/HexEncoding.java b/tests/tests/provider/src/libcore/util/HexEncoding.java
new file mode 100644
index 0000000..992acbd
--- /dev/null
+++ b/tests/tests/provider/src/libcore/util/HexEncoding.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
+ * @hide
+ */
+public class HexEncoding {
+
+    /** Hidden constructor to prevent instantiation. */
+    private HexEncoding() {}
+
+    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+
+    /**
+     * Encodes the provided data as a sequence of hexadecimal characters.
+     */
+    public static char[] encode(byte[] data) {
+        return encode(data, 0, data.length);
+    }
+
+    /**
+     * Encodes the provided data as a sequence of hexadecimal characters.
+     */
+    public static char[] encode(byte[] data, int offset, int len) {
+        char[] result = new char[len * 2];
+        for (int i = 0; i < len; i++) {
+            byte b = data[offset + i];
+            int resultIndex = 2 * i;
+            result[resultIndex] = (HEX_DIGITS[(b >>> 4) & 0x0f]);
+            result[resultIndex + 1] = (HEX_DIGITS[b & 0x0f]);
+        }
+
+        return result;
+    }
+
+    /**
+     * Encodes the provided data as a sequence of hexadecimal characters.
+     */
+    public static String encodeToString(byte[] data) {
+        return new String(encode(data));
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
+     * are not allowed.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decode(String encoded) throws IllegalArgumentException {
+        return decode(encoded.toCharArray());
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+     * is {@code true} odd-length inputs are allowed and the first character is interpreted
+     * as the lower bits of the first result byte.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decode(String encoded, boolean allowSingleChar) throws IllegalArgumentException {
+        return decode(encoded.toCharArray(), allowSingleChar);
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
+     * are not allowed.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decode(char[] encoded) throws IllegalArgumentException {
+        return decode(encoded, false);
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+     * is {@code true} odd-length inputs are allowed and the first character is interpreted
+     * as the lower bits of the first result byte.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decode(char[] encoded, boolean allowSingleChar) throws IllegalArgumentException {
+        int resultLengthBytes = (encoded.length + 1) / 2;
+        byte[] result = new byte[resultLengthBytes];
+
+        int resultOffset = 0;
+        int i = 0;
+        if (allowSingleChar) {
+            if ((encoded.length % 2) != 0) {
+                // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
+                result[resultOffset++] = (byte) toDigit(encoded, i);
+                i++;
+            }
+        } else {
+            if ((encoded.length % 2) != 0) {
+                throw new IllegalArgumentException("Invalid input length: " + encoded.length);
+            }
+        }
+
+        for (int len = encoded.length; i < len; i += 2) {
+            result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
+        }
+
+        return result;
+    }
+
+    private static int toDigit(char[] str, int offset) throws IllegalArgumentException {
+        // NOTE: that this isn't really a code point in the traditional sense, since we're
+        // just rejecting surrogate pairs outright.
+        int pseudoCodePoint = str[offset];
+
+        if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') {
+            return pseudoCodePoint - '0';
+        } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') {
+            return 10 + (pseudoCodePoint - 'a');
+        } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') {
+            return 10 + (pseudoCodePoint - 'A');
+        }
+
+        throw new IllegalArgumentException("Illegal char: " + str[offset] +
+                " at offset " + offset);
+    }
+}
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index e903ab7..f142975 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -36,6 +36,7 @@
 #include <arpa/inet.h>
 #include <linux/ipc.h>
 #include <pthread.h>
+#include <sys/uio.h>
 
 /*
  * Returns true iff this device is vulnerable to CVE-2013-2094.
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index 76f86d5..ef27222 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -28,9 +28,7 @@
 class CertificateData {
   static final String[] CERTIFICATE_DATA = {
       "91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81",
-      "22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66",
       "D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0",
-      "C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB",
       "69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB",
       "92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F",
       "75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE",
@@ -49,17 +47,19 @@
       "1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA",
       "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
       "74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE",
+      "2D:0D:52:14:FF:9E:AD:99:24:01:74:20:47:6E:6C:85:27:27:F5:43",
+      "28:F9:78:16:19:7A:FF:18:25:18:AA:44:FE:C1:A0:CE:5C:B6:4C:8A",
       "31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA",
       "B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB",
       "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
       "2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E",
-      "79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B",
       "A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36",
       "59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9",
       "D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74",
       "02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68",
       "76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB",
       "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
+      "E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31",
       "93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17",
       "59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16",
       "50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
@@ -75,6 +75,7 @@
       "74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4:9A",
       "D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC",
       "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
+      "2A:1D:60:27:D9:4A:B1:0A:1C:4D:91:5C:CD:33:A0:CB:3E:2D:54:CB",
       "DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9",
       "22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A",
       "F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC",
@@ -83,7 +84,7 @@
       "43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
       "F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2",
       "05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
-      "70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62",
+      "30:D4:24:6F:07:FF:DB:91:89:8A:0B:E9:49:66:11:EB:8C:5E:46:E5",
       "D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
       "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
       "4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
@@ -109,11 +110,9 @@
       "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
       "D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58",
       "32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96",
-      "79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E",
+      "80:94:64:0E:B5:A7:A1:CA:11:9C:1F:DD:D5:9F:81:02:63:A7:FB:D1",
       "67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0",
-      "FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D",
       "4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C",
-      "33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9",
       "DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4",
       "36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7",
       "37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27",
@@ -134,6 +133,7 @@
       "58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD",
       "F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
       "3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04",
+      "D2:73:96:2A:2A:5E:39:9F:73:3F:E1:C7:1E:64:3F:03:38:34:FC:4D",
       "03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD",
       "1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F",
       "DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4",
@@ -151,6 +151,7 @@
       "9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8",
       "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
       "4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A",
+      "A3:A1:B0:6F:24:61:23:4A:E3:36:A5:C2:37:FC:A6:FF:DD:F0:D7:3A",
       "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
       "01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6",
       "0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED",
@@ -159,7 +160,7 @@
       "E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79",
       "89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
       "7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
-      "6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1",
+      "E1:C9:50:E6:EF:22:F8:4C:56:45:72:8B:92:20:60:D7:D5:A7:A3:E8",
       "4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5",
       "5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A",
       "8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16",
diff --git a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
index 349e2c9..69a4a4a 100644
--- a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
+++ b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
@@ -61,9 +61,20 @@
      * Check expectations of being able to read/execute dex2oat.
      */
     protected static void checkDex2oatAccess(boolean expectedAllowed) throws Exception {
-        File dex2oatBinary = new File("/system/bin/dex2oat");
-        assertTrue(dex2oatBinary.exists());
+        // First check whether there is an Android Runtime APEX dex2oat binary.
+        File dex2oatRuntimeApexBinary = new File("/apex/com.android.runtime/bin/dex2oat");
+        if (dex2oatRuntimeApexBinary.exists()) {
+          checkDex2oatBinaryAccess(dex2oatRuntimeApexBinary, expectedAllowed);
+        }
+        // Also check whether there is a "legacy" system binary.
+        File dex2oatSystemBinary = new File("/system/bin/dex2oat");
+        if (dex2oatSystemBinary.exists()) {
+          checkDex2oatBinaryAccess(dex2oatSystemBinary, expectedAllowed);
+        }
+    }
 
+    private static void checkDex2oatBinaryAccess(File dex2oatBinary, boolean expectedAllowed)
+        throws Exception {
         // Check permissions.
         assertEquals(expectedAllowed, dex2oatBinary.canRead());
         assertEquals(expectedAllowed, dex2oatBinary.canExecute());
diff --git a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
index 4ccc725..92e1070 100644
--- a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
@@ -60,4 +60,8 @@
             "Actual value: ";
         appDataContext(context, msg);
     }
+
+    public void testDex2oat() throws Exception {
+        checkDex2oatAccess(true);
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 436150b..a6d9fc1 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -64,6 +64,7 @@
 
     public static final int FLAG_REGISTER = 0x1;
     public static final int FLAG_ENABLE = 0x2;
+    public static final int FLAG_SET_DEFAULT = 0x4;
 
     private static int sCounter = 5549999;
 
@@ -90,6 +91,8 @@
 
     InCallServiceCallbacks mInCallCallbacks;
     String mPreviousDefaultDialer = null;
+    PhoneAccountHandle mPreviousDefaultOutgoingAccount = null;
+    boolean mShouldRestoreDefaultOutgoingAccount = false;
     MockConnectionService connectionService = null;
 
     HandlerThread mPhoneStateListenerThread;
@@ -194,6 +197,15 @@
             assertPhoneAccountEnabled(TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
         }
 
+        if ((flags & FLAG_SET_DEFAULT) != 0) {
+            mPreviousDefaultOutgoingAccount = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+            mShouldRestoreDefaultOutgoingAccount = true;
+            TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                    TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+            // Wait till the adb commands have executed and the default has changed.
+            assertPhoneAccountIsDefault(TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+        }
+
         return TestUtils.TEST_PHONE_ACCOUNT;
     }
 
@@ -204,7 +216,13 @@
         mTelecomManager.unregisterPhoneAccount(accountHandle);
         CtsConnectionService.tearDown();
         assertCtsConnectionServiceUnbound();
+        if (mShouldRestoreDefaultOutgoingAccount) {
+            TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                    mPreviousDefaultOutgoingAccount);
+        }
         this.connectionService = null;
+        mPreviousDefaultOutgoingAccount = null;
+        mShouldRestoreDefaultOutgoingAccount = false;
     }
 
     protected void startCallTo(Uri address, PhoneAccountHandle accountHandle) {
@@ -1065,6 +1083,26 @@
         );
     }
 
+    void assertPhoneAccountIsDefault(final PhoneAccountHandle handle) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        PhoneAccountHandle phoneAccountHandle =
+                                mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+                        return (phoneAccountHandle != null && phoneAccountHandle.equals(handle));
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Failed to set default phone account to " + handle
+        );
+    }
+
     void assertCtsConnectionServiceUnbound() {
         if (CtsConnectionService.isBound()) {
             assertTrue("CtsConnectionService not yet unbound!",
diff --git a/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
new file mode 100755
index 0000000..9d73e43
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecom.cts;
+
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+/**
+ * Tests use of APIs related to changing the default outgoing phone account.
+ */
+public class DefaultPhoneAccountTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+    }
+
+    /**
+     * Verifies that {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} is able to
+     * retrieve the user-selected outgoing phone account.
+     * Given that there is a user-selected default, also verifies that
+     * {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} reports this value as well.
+     * Note: This test depends on
+     * {@code TelecomManager#setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle)} being run
+     * through the telecom shell command in order to change the user-selected default outgoing
+     * account.
+     * @throws Exception
+     */
+    public void testDefaultIsSet() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        // Make sure to set the default outgoing phone account to the new connection service
+        setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE | FLAG_SET_DEFAULT);
+
+        PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+        assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, handle);
+
+        PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+                PhoneAccount.SCHEME_TEL);
+        assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, defaultOutgoing);
+    }
+
+    /**
+     * Verifies operation of the {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} API
+     * where there is NO user selected default outgoing phone account.
+     * In AOSP, this mimics the user having changed the
+     * Phone --> Settings --> Call Settings --> Calling accounts --> Make Calls With
+     * option to "Ask first".
+     *
+     * The test assumes that a device either has a single sim, or has multiple sims.
+     * In either case, it registers another TEL outgoing calling account.
+     *
+     * We can expect two things:
+     * 1. {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} returns null, since the
+     *    "ask first" option was chosen.
+     * 2. {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} returns null, since there is
+     *    now 2 or more potential outgoing phone accounts with the TEL scheme.
+     * @throws Exception
+     */
+    public void testGetDefaultOutgoingNoUserSelected() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        PhoneAccountHandle previousOutgoingPhoneAccount =
+                mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+
+        // Clear the default outgoing phone account; this is the same as saying "ask every time" in
+        // the user settings.
+        TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                null /* clear default */);
+        try {
+            // Register another TEL URI phone account; since we expect devices to have at minimum
+            // 1 sim, this ensures that we have a scenario where there are multiple potential
+            // outgoing phone accounts with the TEL scheme.
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+
+            // There should be NO user selected default outgoing account (we cleared it).
+            PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+            assertEquals(null, handle);
+
+            // There should be multiple potential TEL phone accounts now, so we expect null here.
+            PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+                    PhoneAccount.SCHEME_TEL);
+            assertEquals(null, defaultOutgoing);
+        } finally {
+            // Restore the default outgoing phone account.
+            TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                    previousOutgoingPhoneAccount);
+        }
+    }
+
+    /**
+     * Verifies correct operation of the
+     * {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} API.
+     * The purpose of this CTS test is to verify the following scenarios:
+     * 1. Where there is NO user selected default outgoing phone account and there is a single
+     *    potential phone account, that phone account should be returned.
+     * 2. Where there is NO user selected default outgoing phone account and there are multiple
+     *    potential phone accounts, null should be returned.
+     * This test performs this operation using a test URI scheme to remove dependencies on the
+     * number of potential sims in a device, however the test cases above should pass even if the
+     * TEL uri scheme was being tested.
+     * @throws Exception
+     */
+    public void testGetDefaultOutgoingPhoneAccountOneOrMany() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        PhoneAccountHandle previousOutgoingPhoneAccount =
+                mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+
+        // Clear the default outgoing phone account; this is the same as saying "ask every time" in
+        // the user settings.
+        TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                null /* clear default */);
+
+        try {
+            // Lets register a new phone account using a test URI scheme 'foobuzz' (this avoids
+            // conflicts with any sims on the device).
+            registerAndEnablePhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_1);
+
+            // There should be NO user selected default outgoing account (we cleared it above).
+            PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+            assertEquals(null, handle);
+
+            // There should be a single potential phone account in the 'foobuzz' scheme, so it
+            // should be reported as the default outgoing phone account.
+            PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+                    TestUtils.TEST_URI_SCHEME);
+            assertEquals(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1, defaultOutgoing);
+
+            // Next, lets register another new phone account using the test URI scheme 'foobuzz'.
+            registerAndEnablePhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_2);
+
+            // There should still be NO user selected default outgoing account (we cleared it
+            // above).
+            handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+            assertEquals(null, handle);
+
+            // Now that there are two potential outgoing accounts in the same scheme and nothing is
+            // chosen as the default, the default outgoing phone account should be "null".
+            defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+                    TestUtils.TEST_URI_SCHEME);
+            assertEquals(null, defaultOutgoing);
+        } finally {
+            mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1);
+            mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2);
+
+            // Restore the default outgoing phone account.
+            TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+                    previousOutgoingPhoneAccount);
+        }
+    }
+
+    private void registerAndEnablePhoneAccount(PhoneAccount phoneAccount) throws Exception {
+        mTelecomManager.registerPhoneAccount(phoneAccount);
+        TestUtils.enablePhoneAccount(getInstrumentation(), phoneAccount.getAccountHandle());
+        // Wait till the adb commands have executed and account is enabled in Telecom database.
+        assertPhoneAccountEnabled(phoneAccount.getAccountHandle());
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index d955efc..38e1a25 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -64,6 +64,7 @@
     // Non-final to allow modification by tests not in this package (e.g. permission-related
     // tests in the Telecom2 test package.
     public static String PACKAGE = "android.telecom.cts";
+    public static final String TEST_URI_SCHEME = "foobuzz";
     public static final String COMPONENT = "android.telecom.cts.CtsConnectionService";
     public static final String SELF_MANAGED_COMPONENT =
             "android.telecom.cts.CtsSelfManagedConnectionService";
@@ -75,6 +76,14 @@
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID_1);
     public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE_2 =
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID_2);
+    public static final String DEFAULT_TEST_ACCOUNT_1_ID = "ctstest_DEFAULT_TEST_ID_1";
+    public static final String DEFAULT_TEST_ACCOUNT_2_ID = "ctstest_DEFAULT_TEST_ID_2";
+    public static final PhoneAccountHandle TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1 =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT),
+                    DEFAULT_TEST_ACCOUNT_1_ID);
+    public static final PhoneAccountHandle TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2 =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT),
+                    DEFAULT_TEST_ACCOUNT_2_ID);
     public static final PhoneAccountHandle TEST_HANDOVER_SRC_PHONE_ACCOUNT_HANDLE =
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), "handoverFrom");
     public static final PhoneAccountHandle TEST_HANDOVER_DEST_PHONE_ACCOUNT_HANDLE =
@@ -123,6 +132,22 @@
             .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
             .build();
 
+    public static final PhoneAccount TEST_DEFAULT_PHONE_ACCOUNT_1 = PhoneAccount.builder(
+            TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1, "Default Test 1")
+            .setAddress(Uri.parse("foobuzz:testuri1"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+            .setHighlightColor(Color.RED)
+            .setShortDescription("Default Test 1")
+            .addSupportedUriScheme(TEST_URI_SCHEME)
+            .build();
+    public static final PhoneAccount TEST_DEFAULT_PHONE_ACCOUNT_2 = PhoneAccount.builder(
+            TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2, "Default Test 2")
+            .setAddress(Uri.parse("foobuzz:testuri2"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+            .setHighlightColor(Color.RED)
+            .setShortDescription("Default Test 2")
+            .addSupportedUriScheme(TEST_URI_SCHEME)
+            .build();
     private static final Bundle SUPPORTS_HANDOVER_FROM_EXTRAS = new Bundle();
     private static final Bundle SUPPORTS_HANDOVER_TO_EXTRAS = new Bundle();
     static {
@@ -153,7 +178,6 @@
             .build();
     public static final String REMOTE_ACCOUNT_LABEL = "CTSRemoteConnectionService";
     public static final String SELF_MANAGED_ACCOUNT_LABEL = "android.telecom.cts";
-    public static final String TEST_URI_SCHEME = "foobuzz";
     public static final PhoneAccount TEST_SELF_MANAGED_PHONE_ACCOUNT_3 = PhoneAccount.builder(
             TEST_SELF_MANAGED_HANDLE_3, SELF_MANAGED_ACCOUNT_LABEL)
             .setAddress(Uri.fromParts(TEST_URI_SCHEME, "test@test.com", null))
@@ -203,6 +227,9 @@
 
     private static final String COMMAND_REGISTER_SIM = "telecom register-sim-phone-account ";
 
+    private static final String COMMAND_SET_DEFAULT_PHONE_ACCOUNT =
+            "telecom set-user-selected-outgoing-phone-account ";
+
     private static final String COMMAND_WAIT_ON_HANDLERS = "telecom wait-on-handlers";
 
     public static final String MERGE_CALLER_NAME = "calls-merged";
@@ -255,6 +282,19 @@
                 + handle.getId() + " " + currentUserSerial + " " + label + " " + address);
     }
 
+    public static void setDefaultOutgoingPhoneAccount(Instrumentation instrumentation,
+            PhoneAccountHandle handle) throws Exception {
+        if (handle != null) {
+            final ComponentName component = handle.getComponentName();
+            final long currentUserSerial = getCurrentUserSerialNumber(instrumentation);
+            executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_PHONE_ACCOUNT
+                    + component.getPackageName() + "/" + component.getClassName() + " "
+                    + handle.getId() + " " + currentUserSerial);
+        } else {
+            executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_PHONE_ACCOUNT);
+        }
+    }
+
     public static void waitOnAllHandlers(Instrumentation instrumentation) throws Exception {
         executeShellCommand(instrumentation, COMMAND_WAIT_ON_HANDLERS);
     }
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index 6f3d71a..85e22f1 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2008 The Android Open Source Project
+#
+# Copyright (C) 2019 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.
@@ -11,42 +12,6 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+#
 
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_JAVA_LIBRARIES := telephony-common
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    ctstestrunner \
-    compatibility-device-util \
-    truth-prebuilt
-
-LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-                   $(call all-java-files-under, EmbmsMiddlewareTestApp) \
-                   $(call all-Iaidl-files-under, EmbmsMiddlewareTestApp)
-
-LOCAL_AIDL_INCLUDES := EmbmsMiddlewareTestApp/aidl/
-
-LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-# uncomment when b/13250611 is fixed
-#LOCAL_SDK_VERSION := current
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
-LOCAL_JAVA_LIBRARIES += android.test.base.stubs
-
-include $(BUILD_CTS_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/Android.bp b/tests/tests/telephony/TestSmsRetrieverApp/Android.bp
new file mode 100644
index 0000000..d0c1a74
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Google Inc.
+//
+// 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.
+
+android_test {
+    name: "TestSmsRetrieverApp",
+
+    srcs: ["src/**/*.kt", "src/**/*.java"],
+
+    static_libs: [
+        "compatibility-device-util",
+    ],
+
+    test_suites: [
+        "cts",
+    ],
+}
\ No newline at end of file
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml b/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml
new file mode 100644
index 0000000..2ac0079f
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.telephony.cts.smsretriever">
+
+    <application android:label="TestSmsRetrieverApp">
+        <activity
+            android:name="android.telephony.cts.smsretriever.MainActivity"
+            android:exported="true"/>
+	<receiver android:name="android.telephony.cts.smsretriever.SmsRetrieverBroadcastReceiver">
+            <intent-filter>
+                <action android:name="android.telephony.cts.action.SMS_RETRIEVED"></action>
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml b/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml
new file mode 100644
index 0000000..8758e66
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+</RelativeLayout>
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java
new file mode 100644
index 0000000..1f89db5
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 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.telephony.cts.smsretriever;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.telephony.SmsManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class MainActivity extends Activity {
+    private static final String SMS_RETRIEVER_ACTION = "CTS_SMS_RETRIEVER_ACTION";
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent("android.telephony.cts.action.SMS_RETRIEVED")
+                        .setComponent(new ComponentName(
+                                "android.telephony.cts.smsretriever",
+                                "android.telephony.cts.smsretriever.SmsRetrieverBroadcastReceiver"));
+        PendingIntent pIntent = PendingIntent.getBroadcast(
+                getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+        String token = null;
+        try {
+            token = SmsManager.getDefault().createAppSpecificSmsTokenWithPackageInfo(
+                    "testprefix1,testprefix2", pIntent);
+        } catch (Exception e) {
+            Log.w("MainActivity", "received Exception e:" + e);
+        }
+
+        if (getIntent().getAction() == null) {
+            Bundle result = new Bundle();
+            result.putString("class", getClass().getName());
+            result.putString("token", token);
+            sendResult(result);
+        } else {
+            // Launched by broadcast receiver
+            assertThat(getIntent().getStringExtra("message"),
+                    equalTo("testprefix1This is a test message" + token));
+            Intent bIntent = new Intent(SMS_RETRIEVER_ACTION);
+            sendBroadcast(bIntent);
+            finish();
+        }
+    }
+
+    public void sendResult(Bundle result) {
+        getIntent().<RemoteCallback>getParcelableExtra("callback").sendResult(result);
+    }
+
+
+}
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java
new file mode 100644
index 0000000..ebb17b9
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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.telephony.cts.smsretriever;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.telephony.SmsManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class SmsRetrieverBroadcastReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+          if (intent.getAction().equals("android.telephony.cts.action.SMS_RETRIEVED")) {
+              context.startActivity(new Intent("any.action")
+                      .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                      .setComponent(new ComponentName("android.telephony.cts.smsretriever",
+                              "android.telephony.cts.smsretriever.MainActivity"))
+                      .putExtra("message", intent.getStringExtra(SmsManager.EXTRA_SMS_MESSAGE)));
+          }
+        }
+}
diff --git a/tests/tests/telephony/current/Android.mk b/tests/tests/telephony/current/Android.mk
new file mode 100644
index 0000000..6f3d71a
--- /dev/null
+++ b/tests/tests/telephony/current/Android.mk
@@ -0,0 +1,52 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := telephony-common
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner \
+    compatibility-device-util \
+    truth-prebuilt
+
+LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+                   $(call all-java-files-under, EmbmsMiddlewareTestApp) \
+                   $(call all-Iaidl-files-under, EmbmsMiddlewareTestApp)
+
+LOCAL_AIDL_INCLUDES := EmbmsMiddlewareTestApp/aidl/
+
+LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+# uncomment when b/13250611 is fixed
+#LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
+LOCAL_JAVA_LIBRARIES += android.test.base.stubs
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/AndroidManifest.xml
rename to tests/tests/telephony/current/AndroidManifest.xml
diff --git a/tests/tests/telephony/AndroidTest.xml b/tests/tests/telephony/current/AndroidTest.xml
similarity index 97%
rename from tests/tests/telephony/AndroidTest.xml
rename to tests/tests/telephony/current/AndroidTest.xml
index 4fabab8..44a4c68 100644
--- a/tests/tests/telephony/AndroidTest.xml
+++ b/tests/tests/telephony/current/AndroidTest.xml
@@ -28,6 +28,7 @@
         <option name="test-file-name" value="EmbmsMiddlewareCtsTestApp.apk"/>
         <option name="test-file-name" value="TestSmsApp22.apk"/>
         <option name="test-file-name" value="TestSmsApp.apk"/>
+        <option name="test-file-name" value="TestSmsRetrieverApp.apk"/>
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.telephony.cts" />
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/Android.mk b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/Android.mk
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/Android.mk
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/Android.mk
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/AndroidManifest.xml
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
diff --git a/tests/tests/telephony/preconditions/Android.mk b/tests/tests/telephony/current/preconditions/Android.mk
similarity index 100%
rename from tests/tests/telephony/preconditions/Android.mk
rename to tests/tests/telephony/current/preconditions/Android.mk
diff --git a/tests/tests/telephony/preconditions/app/Android.mk b/tests/tests/telephony/current/preconditions/app/Android.mk
similarity index 100%
rename from tests/tests/telephony/preconditions/app/Android.mk
rename to tests/tests/telephony/current/preconditions/app/Android.mk
diff --git a/tests/tests/telephony/preconditions/app/AndroidManifest.xml b/tests/tests/telephony/current/preconditions/app/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/preconditions/app/AndroidManifest.xml
rename to tests/tests/telephony/current/preconditions/app/AndroidManifest.xml
diff --git a/tests/tests/telephony/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java b/tests/tests/telephony/current/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
similarity index 100%
rename from tests/tests/telephony/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
rename to tests/tests/telephony/current/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
diff --git a/tests/tests/telephony/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java b/tests/tests/telephony/current/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
similarity index 100%
rename from tests/tests/telephony/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
rename to tests/tests/telephony/current/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierCapability.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierCapability.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellLocationTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CellLocationTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java b/tests/tests/telephony/current/src/android/telephony/cts/ComposeSmsActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java
rename to tests/tests/telephony/current/src/android/telephony/cts/ComposeSmsActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java b/tests/tests/telephony/current/src/android/telephony/cts/HeadlessSmsSendService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/HeadlessSmsSendService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsPduProvider.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsPduProvider.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsReceiver.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsReceiver.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MockVisualVoicemailService.java b/tests/tests/telephony/current/src/android/telephony/cts/MockVisualVoicemailService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MockVisualVoicemailService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MockVisualVoicemailService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/NeighboringCellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/NeighboringCellInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/NeighboringCellInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/NeighboringCellInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/PermissionlessVisualVoicemailService.java b/tests/tests/telephony/current/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
new file mode 100644
index 0000000..b0d8f18
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -0,0 +1,824 @@
+/*
+ * Copyright (C) 2009 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.telephony.cts;
+
+import android.content.Context;
+import android.os.Looper;
+import android.telephony.CellInfo;
+import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.TestThread;
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class PhoneStateListenerTest extends AndroidTestCase{
+
+    public static final long WAIT_TIME = 1000;
+
+    private boolean mOnCallForwardingIndicatorChangedCalled;
+    private boolean mOnCallStateChangedCalled;
+    private boolean mOnCellLocationChangedCalled;
+    private boolean mOnUserMobileDataStateChanged;
+    private boolean mOnDataActivityCalled;
+    private boolean mOnDataConnectionStateChangedCalled;
+    private boolean mOnDataConnectionStateChangedWithNetworkTypeCalled;
+    private boolean mOnMessageWaitingIndicatorChangedCalled;
+    private boolean mOnCellInfoChangedCalled;
+    private boolean mOnServiceStateChangedCalled;
+    private boolean mOnSignalStrengthChangedCalled;
+    private boolean mOnPreciseCallStateChangedCalled;
+    private boolean mOnCallDisconnectCauseChangedCalled;
+    private boolean mOnPreciseDataConnectionStateChanged;
+    private boolean mOnRadioPowerStateChangedCalled;
+    private boolean mVoiceActivationStateChangedCalled;
+    private boolean mSrvccStateChangedCalled;
+    @TelephonyManager.RadioPowerState private int mRadioPowerState;
+    @TelephonyManager.SimActivationState private int mVoiceActivationState;
+    private PreciseDataConnectionState mPreciseDataConnectionState;
+    private PreciseCallState mPreciseCallState;
+    private SignalStrength mSignalStrength;
+    private TelephonyManager mTelephonyManager;
+    private PhoneStateListener mListener;
+    private final Object mLock = new Object();
+    private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
+    private static ConnectivityManager mCm;
+    private static final List<Integer> DATA_CONNECTION_STATE = Arrays.asList(
+            TelephonyManager.DATA_CONNECTED,
+            TelephonyManager.DATA_DISCONNECTED,
+            TelephonyManager.DATA_CONNECTING,
+            TelephonyManager.DATA_UNKNOWN,
+            TelephonyManager.DATA_SUSPENDED
+    );
+    private static final List<Integer> PRECISE_CALL_STATE = Arrays.asList(
+            PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+            PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+            PreciseCallState.PRECISE_CALL_STATE_DIALING,
+            PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
+            PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING,
+            PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+            PreciseCallState.PRECISE_CALL_STATE_IDLE,
+            PreciseCallState.PRECISE_CALL_STATE_INCOMING,
+            PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+            PreciseCallState.PRECISE_CALL_STATE_WAITING
+    );
+    private Executor mSimpleExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTelephonyManager =
+                (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mListener != null) {
+            // unregister the listener
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+        }
+    }
+
+    public void testPhoneStateListener() {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        Looper.prepare();
+        new PhoneStateListener();
+    }
+
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+
+    public void testOnServiceStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onServiceStateChanged(ServiceState serviceState) {
+                        synchronized(mLock) {
+                            mOnServiceStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnServiceStateChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnServiceStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnServiceStateChangedCalled);
+    }
+
+    public void testOnSignalStrengthChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onSignalStrengthChanged(int asu) {
+                        synchronized(mLock) {
+                            mOnSignalStrengthChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnSignalStrengthChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnSignalStrengthChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnSignalStrengthChangedCalled);
+    }
+
+    public void testOnSignalStrengthsChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                        synchronized(mLock) {
+                            mSignalStrength = signalStrength;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+                Looper.loop();
+            }
+        });
+
+        assertTrue(mSignalStrength == null);
+        t.start();
+
+        synchronized (mLock) {
+            if (mSignalStrength == null) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mSignalStrength != null);
+
+        // Call SignalStrength methods to make sure they do not throw any exceptions
+        mSignalStrength.getCdmaDbm();
+        mSignalStrength.getCdmaEcio();
+        mSignalStrength.getEvdoDbm();
+        mSignalStrength.getEvdoEcio();
+        mSignalStrength.getEvdoSnr();
+        mSignalStrength.getGsmBitErrorRate();
+        mSignalStrength.getGsmSignalStrength();
+        mSignalStrength.isGsm();
+        mSignalStrength.getLevel();
+    }
+
+    public void testOnMessageWaitingIndicatorChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onMessageWaitingIndicatorChanged(boolean mwi) {
+                        synchronized(mLock) {
+                            mOnMessageWaitingIndicatorChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnMessageWaitingIndicatorChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnMessageWaitingIndicatorChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnMessageWaitingIndicatorChangedCalled);
+    }
+
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+    public void testOnPreciseCallStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
+                        synchronized (mLock) {
+                            mOnPreciseCallStateChangedCalled = true;
+                            mPreciseCallState = preciseCallState;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_PRECISE_CALL_STATE));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mOnPreciseCallStateChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnPreciseCallStateChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        Log.d(TAG, "testOnPreciseCallStateChanged: " + mOnPreciseCallStateChangedCalled);
+        assertThat(mOnPreciseCallStateChangedCalled).isTrue();
+        assertThat(mPreciseCallState.getForegroundCallState()).isIn(PRECISE_CALL_STATE);
+        assertThat(mPreciseCallState.getBackgroundCallState()).isIn(PRECISE_CALL_STATE);
+        assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
+    }
+
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+    public void testOnCallDisconnectCauseChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCallDisconnectCauseChanged(int disconnectCause,
+                                                             int preciseDisconnectCause) {
+                        synchronized (mLock) {
+                            mOnCallDisconnectCauseChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                            (tm) -> tm.listen(mListener,
+                                    PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnCallDisconnectCauseChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
+    }
+
+    public void testOnPhoneStateListenerExecutorWithSrvccChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener(mSimpleExecutor) {
+                    @Override
+                    public void onSrvccStateChanged(int state) {
+                        synchronized (mLock) {
+                            mSrvccStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mSrvccStateChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mSrvccStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertThat(mSrvccStateChangedCalled).isTrue();
+        t.checkException();
+        Log.d(TAG, "testOnPhoneStateListenerExecutorWithSrvccChanged");
+    }
+
+    /*
+    * The tests below rely on the framework to immediately call the installed listener upon
+    * registration. There is no simple way to emulate state changes for testing the listeners.
+    */
+    public void testOnRadioPowerStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onRadioPowerStateChanged(int state) {
+                        synchronized(mLock) {
+                            mRadioPowerState = state;
+                            mOnRadioPowerStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+                Looper.loop();
+            }
+        });
+        assertThat(mOnRadioPowerStateChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnRadioPowerStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        Log.d(TAG, "testOnRadioPowerStateChanged: " + mRadioPowerState);
+        assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
+    }
+
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+    public void testOnVoiceActivationStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onVoiceActivationStateChanged(int state) {
+                        synchronized(mLock) {
+                            mVoiceActivationState = state;
+                            mVoiceActivationStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE));
+                Looper.loop();
+            }
+        });
+        assertThat(mVoiceActivationStateChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mVoiceActivationStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        Log.d(TAG, "onVoiceActivationStateChanged: " + mVoiceActivationState);
+        int state = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getVoiceActivationState());
+        assertEquals(state, mVoiceActivationState);
+    }
+
+    /*
+    * The tests below rely on the framework to immediately call the installed listener upon
+    * registration. There is no simple way to emulate state changes for testing the listeners.
+    */
+    public void testOnPreciseDataConnectionStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onPreciseDataConnectionStateChanged(
+                            PreciseDataConnectionState state) {
+                        synchronized(mLock) {
+                            mOnPreciseDataConnectionStateChanged = true;
+                            mPreciseDataConnectionState = state;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnPreciseDataConnectionStateChanged){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertThat(mOnPreciseDataConnectionStateChanged).isTrue();
+        assertThat(mPreciseDataConnectionState.getDataConnectionState())
+                .isIn(DATA_CONNECTION_STATE);
+        // basic test to verify there is no exception thrown.
+        mPreciseDataConnectionState.getDataConnectionApnTypeBitMask();
+        mPreciseDataConnectionState.getDataConnectionApn();
+        mPreciseDataConnectionState.getDataConnectionFailCause();
+    }
+
+    public void testOnCallForwardingIndicatorChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            @Override
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCallForwardingIndicatorChanged(boolean cfi) {
+                        synchronized(mLock) {
+                            mOnCallForwardingIndicatorChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCallForwardingIndicatorChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnCallForwardingIndicatorChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnCallForwardingIndicatorChangedCalled);
+    }
+
+    public void testOnCellLocationChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCellLocationChanged(CellLocation location) {
+                        synchronized(mLock) {
+                            mOnCellLocationChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCellLocationChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnCellLocationChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnCellLocationChangedCalled);
+    }
+
+    public void testOnCallStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCallStateChanged(int state, String incomingNumber) {
+                        synchronized(mLock) {
+                            mOnCallStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnCallStateChangedCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnCallStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnCallStateChangedCalled);
+    }
+
+    public void testOnDataConnectionStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onDataConnectionStateChanged(int state) {
+                        synchronized(mLock) {
+                            mOnDataConnectionStateChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                    @Override
+                    public void onDataConnectionStateChanged(int state, int networkType) {
+                        synchronized(mLock) {
+                            mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnDataConnectionStateChangedCalled);
+        assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnDataConnectionStateChangedCalled ||
+                    !mOnDataConnectionStateChangedWithNetworkTypeCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnDataConnectionStateChangedCalled);
+        assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+    }
+
+    public void testOnDataActivity() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onDataActivity(int direction) {
+                        synchronized(mLock) {
+                            mOnDataActivityCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnDataActivityCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnDataActivityCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnDataActivityCalled);
+    }
+
+    public void testOnCellInfoChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onCellInfoChanged(List<CellInfo> cellInfo) {
+                        synchronized(mLock) {
+                            mOnCellInfoChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnDataActivityCalled);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnCellInfoChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnCellInfoChangedCalled);
+    }
+
+    public void testOnUserMobileDataStateChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onUserMobileDataStateChanged(boolean state) {
+                        synchronized(mLock) {
+                            mOnUserMobileDataStateChanged = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(
+                        mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
+
+                Looper.loop();
+            }
+        });
+
+        assertFalse(mOnUserMobileDataStateChanged);
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnUserMobileDataStateChanged){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertTrue(mOnUserMobileDataStateChanged);
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java b/tests/tests/telephony/current/src/android/telephony/cts/RadioAccessSpecifierTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/RadioAccessSpecifierTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
new file mode 100644
index 0000000..cb87173
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.cts;
+
+import static android.telephony.NetworkRegistrationState.NR_STATUS_CONNECTED;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.os.Parcel;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.CellSignalStrength;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+
+/**
+ * Test SignalStrength to ensure that valid data is being reported and that invalid data is
+ * not reported.
+ */
+public class SignalStrengthTest extends AndroidTestCase {
+    private static final String TAG = "SignalStrengthTest";
+
+    private TelephonyManager mTm;
+    private PackageManager mPm;
+
+    // Check that the device is camped on a cellular cell */
+    private boolean isCamped() {
+        ServiceState ss = mTm.getServiceState();
+        if (ss == null) return false;
+        return (ss.getState() == ServiceState.STATE_IN_SERVICE
+                || ss.getState() == ServiceState.STATE_EMERGENCY_ONLY);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTm = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mPm = getContext().getPackageManager();
+    }
+
+    public void testSignalStrength() throws Throwable {
+        if (!mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+            return;
+        }
+
+        if (!isCamped()) fail("Device is not camped on cellular");
+
+        SignalStrength ss = mTm.getSignalStrength();
+        assertNotNull("TelephonyManager.getSignalStrength() returned NULL!", ss);
+
+        List<CellSignalStrength> signalStrengths = ss.getCellSignalStrengths();
+
+        assertTrue("No Signal Strength Information Reported!", !signalStrengths.isEmpty());
+
+        Set<Class<?>> types = new HashSet<Class<?>>();
+
+        Class<?> type = getSignalStrengthTypeForNetworkType(mTm.getDataNetworkType());
+        if (type != null) types.add(type);
+
+        type = getSignalStrengthTypeForNetworkType(mTm.getNetworkType());
+        if (type != null) types.add(type);
+
+        // Blocked by b/123096279
+        /*
+        for (CellSignalStrength css : signalStrengths) {
+            assertTrue("Invalid SignalStrength type detected" + css.getClass(),
+                    types.contains(css.getClass())
+                            || css instanceof CellSignalStrengthNr && isUsingEnDc());
+        }
+        */
+    }
+
+    /** Check whether the device is LTE + NR dual connected */
+    private boolean isUsingEnDc() {
+        ServiceState ss = mTm.getServiceState();
+        return false;
+        // blocked by b/123096279
+        // return ss != null && ss.getNrStatus() == NR_STATUS_CONNECTED;
+    }
+
+    /** Get the CellSignalStrength class type that should be returned when using a network type */
+    private static Class<?> getSignalStrengthTypeForNetworkType(int networkType) {
+        switch(networkType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_EDGE: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_GSM:
+                return CellSignalStrengthGsm.class;
+            case TelephonyManager.NETWORK_TYPE_UMTS: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_HSDPA: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_HSUPA: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_HSPA: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                return CellSignalStrengthWcdma.class;
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+                return CellSignalStrengthTdscdma.class;
+            case TelephonyManager.NETWORK_TYPE_CDMA: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_1xRTT: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_EVDO_0: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_EVDO_A: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_EVDO_B: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+                return CellSignalStrengthCdma.class;
+            case TelephonyManager.NETWORK_TYPE_LTE: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_LTE_CA:
+                return CellSignalStrengthLte.class;
+            case TelephonyManager.NETWORK_TYPE_IWLAN: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_IDEN: /* fall through */
+            case TelephonyManager.NETWORK_TYPE_NR: /* fall through */
+            default:
+                return null;
+        }
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
similarity index 93%
rename from tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
index 6eaf46e..208afb0 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
@@ -57,12 +57,14 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.lang.StringBuilder;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -90,6 +92,8 @@
     public static final String SMS_DELIVER_DEFAULT_APP_ACTION = "CTS_SMS_DELIVERY_ACTION_DEFAULT_APP";
     public static final String LEGACY_SMS_APP = "android.telephony.cts.sms23";
     public static final String MODERN_SMS_APP = "android.telephony.cts.sms";
+    private static final String SMS_RETRIEVER_APP = "android.telephony.cts.smsretriever";
+    private static final String SMS_RETRIEVER_ACTION = "CTS_SMS_RETRIEVER_ACTION";
 
     private TelephonyManager mTelephonyManager;
     private PackageManager mPackageManager;
@@ -100,6 +104,7 @@
     private SmsBroadcastReceiver mDataSmsReceiver;
     private SmsBroadcastReceiver mSmsDeliverReceiver;
     private SmsBroadcastReceiver mSmsReceivedReceiver;
+    private SmsBroadcastReceiver mSmsRetrieverReceiver;
     private PendingIntent mSentIntent;
     private PendingIntent mDeliveredIntent;
     private Intent mSendIntent;
@@ -182,6 +187,39 @@
         return longText.equals(actualMessage);
     }
 
+    public void testSmsRetriever() throws Exception {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        assertFalse("[RERUN] SIM card does not provide phone number. Use a suitable SIM Card.",
+                TextUtils.isEmpty(mDestAddr));
+
+        String mccmnc = mTelephonyManager.getSimOperator();
+        setupBroadcastReceivers();
+        init();
+
+        CompletableFuture<Bundle> callbackResult = new CompletableFuture<>();
+
+        mContext.startActivity(new Intent()
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                .setComponent(new ComponentName(
+                        SMS_RETRIEVER_APP, SMS_RETRIEVER_APP + ".MainActivity"))
+                .putExtra("callback", new RemoteCallback(callbackResult::complete)));
+
+
+        Bundle bundle = callbackResult.get(200, TimeUnit.SECONDS);
+        String token = bundle.getString("token");
+        assertThat(bundle.getString("class"), startsWith(SMS_RETRIEVER_APP));
+        assertNotNull(token);
+
+        String composedText = "testprefix1" + mText + token;
+        sendTextMessage(mDestAddr, composedText, null, null);
+
+        assertTrue("[RERUN] SMS retriever message not received. Check signal.",
+                mSmsRetrieverReceiver.waitForCalls(1, TIME_OUT));
+    }
+
     public void testSendAndReceiveMessages() throws Exception {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             return;
@@ -488,6 +526,7 @@
         mDataSmsReceiver.reset();
         mSmsDeliverReceiver.reset();
         mSmsReceivedReceiver.reset();
+        mSmsRetrieverReceiver.reset();
         mReceivedDataSms = false;
         mSentIntent = PendingIntent.getBroadcast(mContext, 0, mSendIntent,
                 PendingIntent.FLAG_ONE_SHOT);
@@ -505,6 +544,7 @@
         IntentFilter smsDeliverIntentFilter = new IntentFilter(SMS_DELIVER_DEFAULT_APP_ACTION);
         IntentFilter smsReceivedIntentFilter =
                 new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
+        IntentFilter smsRetrieverIntentFilter = new IntentFilter(SMS_RETRIEVER_ACTION);
         dataSmsReceivedIntentFilter.addDataScheme("sms");
         dataSmsReceivedIntentFilter.addDataAuthority("localhost", "19989");
 
@@ -513,12 +553,14 @@
         mDataSmsReceiver = new SmsBroadcastReceiver(DATA_SMS_RECEIVED_ACTION);
         mSmsDeliverReceiver = new SmsBroadcastReceiver(SMS_DELIVER_DEFAULT_APP_ACTION);
         mSmsReceivedReceiver = new SmsBroadcastReceiver(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
+        mSmsRetrieverReceiver = new SmsBroadcastReceiver(SMS_RETRIEVER_ACTION);
 
         mContext.registerReceiver(mSendReceiver, sendIntentFilter);
         mContext.registerReceiver(mDeliveryReceiver, deliveryIntentFilter);
         mContext.registerReceiver(mDataSmsReceiver, dataSmsReceivedIntentFilter);
         mContext.registerReceiver(mSmsDeliverReceiver, smsDeliverIntentFilter);
         mContext.registerReceiver(mSmsReceivedReceiver, smsReceivedIntentFilter);
+        mContext.registerReceiver(mSmsRetrieverReceiver, smsRetrieverIntentFilter);
     }
 
     /**
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessageTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessageTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessage_MessageClassTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_MessageClassTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessage_MessageClassTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_MessageClassTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessage_SubmitPduTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsReceiver.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsReceiver.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
similarity index 98%
rename from tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
index 88475d1..58c33be 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
@@ -502,6 +502,13 @@
 
         SmsUsageMonitor monitor = new SmsUsageMonitor(mContext);
         for (ShortCodeTest test : sShortCodeTests) {
+            // It is intended that a short code number in country A may be an emergency number
+            // in country B. It is intended that the destination will be changed because of this
+            // reason. checkDestination() returns CATEGORY_NOT_SHORT_CODE for emergency numbers.
+            if (test.category != CATEGORY_NOT_SHORT_CODE
+                    && PhoneNumberUtils.isEmergencyNumber(test.address, test.countryIso)) {
+                continue;
+            }
             assertEquals("country: " + test.countryIso + " number: " + test.address,
                     test.category, monitor.checkDestination(test.address, test.countryIso));
         }
diff --git a/tests/tests/telephony/src/android/telephony/cts/StubDialerActivity.java b/tests/tests/telephony/current/src/android/telephony/cts/StubDialerActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/StubDialerActivity.java
rename to tests/tests/telephony/current/src/android/telephony/cts/StubDialerActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/StubInCallService.java b/tests/tests/telephony/current/src/android/telephony/cts/StubInCallService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/StubInCallService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/StubInCallService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
similarity index 95%
rename from tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 1fef678..f358d8c 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -43,6 +43,7 @@
 import android.telephony.SubscriptionPlan;
 
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.internal.util.ArrayUtils;
 
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -144,12 +145,32 @@
     @Test
     public void testGetActiveSubscriptionInfoCount() throws Exception {
         if (!isSupported()) return;
-
         assertTrue(mSm.getActiveSubscriptionInfoCount() <=
                 mSm.getActiveSubscriptionInfoCountMax());
     }
 
     @Test
+    public void testIsActiveSubscriptionId() throws Exception {
+        if (!isSupported()) return;
+        assertTrue(mSm.isActiveSubscriptionId(mSubId));
+    }
+
+    @Test
+    public void testGetSubscriptionIds() throws Exception {
+        if (!isSupported()) return;
+        int slotId = SubscriptionManager.getSlotIndex(mSubId);
+        int[] subIds = mSm.getSubscriptionIds(slotId);
+        assertNotNull(subIds);
+        assertTrue(ArrayUtils.contains(subIds, mSubId));
+    }
+
+    @Test
+    public void testIsUsableSubscriptionId() throws Exception {
+        if (!isSupported()) return;
+        assertTrue(SubscriptionManager.isUsableSubIdValue(mSubId));
+    }
+
+    @Test
     public void testActiveSubscriptions() throws Exception {
         if (!isSupported()) return;
 
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
similarity index 71%
rename from tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 68765af..b964292 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -34,10 +34,13 @@
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import static com.google.common.truth.Truth.assertThat;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CellLocation;
+import android.telephony.NetworkRegistrationState;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -55,6 +58,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -67,20 +71,53 @@
 @RunWith(AndroidJUnit4.class)
 public class TelephonyManagerTest {
     private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
     private PackageManager mPackageManager;
     private boolean mOnCellLocationChangedCalled = false;
+    private boolean mServiceStateChangedCalled = false;
+    private boolean mRadioRebootTriggered = false;
+    private boolean mHasRadioPowerOff = false;
     private ServiceState mServiceState;
     private final Object mLock = new Object();
     private static final int TOLERANCE = 1000;
     private PhoneStateListener mListener;
     private static ConnectivityManager mCm;
     private static final String TAG = "TelephonyManagerTest";
+    private static final List<Integer> ROAMING_TYPES = Arrays.asList(
+            ServiceState.ROAMING_TYPE_DOMESTIC,
+            ServiceState.ROAMING_TYPE_INTERNATIONAL,
+            ServiceState.ROAMING_TYPE_NOT_ROAMING,
+            ServiceState.ROAMING_TYPE_UNKNOWN);
+    private static final List<Integer> NETWORK_TYPES = Arrays.asList(
+            TelephonyManager.NETWORK_TYPE_UNKNOWN,
+            TelephonyManager.NETWORK_TYPE_GPRS,
+            TelephonyManager.NETWORK_TYPE_EDGE,
+            TelephonyManager.NETWORK_TYPE_UMTS,
+            TelephonyManager.NETWORK_TYPE_CDMA,
+            TelephonyManager.NETWORK_TYPE_EVDO_0,
+            TelephonyManager.NETWORK_TYPE_EVDO_A,
+            TelephonyManager.NETWORK_TYPE_1xRTT,
+            TelephonyManager.NETWORK_TYPE_HSDPA,
+            TelephonyManager.NETWORK_TYPE_HSUPA,
+            TelephonyManager.NETWORK_TYPE_HSPA,
+            TelephonyManager.NETWORK_TYPE_IDEN,
+            TelephonyManager.NETWORK_TYPE_EVDO_B,
+            TelephonyManager.NETWORK_TYPE_LTE,
+            TelephonyManager.NETWORK_TYPE_EHRPD,
+            TelephonyManager.NETWORK_TYPE_HSPAP,
+            TelephonyManager.NETWORK_TYPE_GSM,
+            TelephonyManager.NETWORK_TYPE_TD_SCDMA,
+            TelephonyManager.NETWORK_TYPE_IWLAN,
+            TelephonyManager.NETWORK_TYPE_LTE_CA,
+            TelephonyManager.NETWORK_TYPE_NR);
 
     @Before
     public void setUp() throws Exception {
         mTelephonyManager =
                 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
         mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mSubscriptionManager = (SubscriptionManager) getContext()
+                .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
         mPackageManager = getContext().getPackageManager();
     }
 
@@ -524,6 +561,22 @@
         assertEquals(mServiceState, mTelephonyManager.getServiceState());
     }
 
+    @Test
+    public void testGetSimLocale() throws InterruptedException {
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG,"skipping test that requires Telephony");
+            return;
+        }
+        if (SubscriptionManager.getDefaultSubscriptionId()
+                == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            fail("Expected SIM inserted");
+        }
+        String locale = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getSimLocale());
+        Log.d(TAG, "testGetSimLocale: " + locale);
+        assertNotNull(locale);
+    }
+
     /**
      * Tests that the device properly reports either a valid IMEI or null.
      */
@@ -567,6 +620,227 @@
     }
 
     /**
+     * Verifies that {@link TelephonyManager#getRadioPowerState()} does not throw any exception
+     * and returns radio on.
+     */
+    @Test
+    public void testGetRadioPowerState() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        // Also verify that no exception is thrown.
+        assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+                TelephonyManager.RADIO_POWER_ON);
+    }
+
+    /**
+     * Verifies that {@link TelephonyManager#setCarrierDataEnabled(boolean)} does not throw any
+     * exception. TODO enhance later if we have an API to get data enabled state.
+     */
+    @Test
+    public void testSetCarrierDataEnabled() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        // Also verify that no exception is thrown.
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                (tm) -> tm.setCarrierDataEnabled(false));
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                (tm) -> tm.setCarrierDataEnabled(true));
+    }
+
+    /**
+     * Verifies that {@link TelephonyManager#rebootRadio()} does not throw any exception
+     * and final radio state is radio power on.
+     */
+    @Test
+    public void testRebootRadio() throws Throwable {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        assertEquals(mTelephonyManager.getServiceState().getState(), ServiceState.STATE_IN_SERVICE);
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onRadioPowerStateChanged(
+                            @TelephonyManager.RadioPowerState int state) {
+                        synchronized (mLock) {
+                            if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
+                                mRadioRebootTriggered = true;
+                                mLock.notify();
+                            } else if (state == TelephonyManager.RADIO_POWER_OFF) {
+                                // reboot must go to power off
+                                mHasRadioPowerOff = true;
+                            }
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+                TelephonyManager.RADIO_POWER_ON);
+        assertThat(mRadioRebootTriggered).isFalse();
+        assertThat(mHasRadioPowerOff).isFalse();
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.rebootRadio());
+        t.start();
+        synchronized (mLock) {
+            // reboot takes longer time
+            if (!mRadioRebootTriggered) {
+                mLock.wait(10000);
+            }
+        }
+        assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+                TelephonyManager.RADIO_POWER_ON);
+        assertThat(mRadioRebootTriggered).isTrue();
+
+        // note, other telephony states might not resumes properly at this point. e.g, service state
+        // might still in the transition from OOS to In service. Thus we need to wait for in
+        // service state before running next tests.
+        t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onServiceStateChanged(ServiceState serviceState) {
+                        synchronized (mLock) {
+                            if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
+                                mServiceStateChangedCalled = true;
+                                mLock.notify();
+                            }
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
+                Looper.loop();
+            }
+        });
+
+        synchronized (mLock) {
+            t.start();
+            if (!mServiceStateChangedCalled) {
+                mLock.wait(10000);
+            }
+        }
+        assertThat(mTelephonyManager.getServiceState().getState()).isEqualTo(
+                ServiceState.STATE_IN_SERVICE);
+    }
+
+    /**
+     * Verifies that {@link TelephonyManager#getAidForAppType(int)} does not throw any exception
+     * for all supported subscription app type.
+     */
+    @Test
+    public void testGetAidForAppType() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_SIM));
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_CSIM));
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_RUIM));
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_ISIM));
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_USIM));
+    }
+
+    /**
+     * Verifies that {@link TelephonyManager#getIsimDomain()} does not throw any exception
+     */
+    @Test
+    public void testGetIsimDomain() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getIsimDomain());
+    }
+
+    /**
+     * Basic test to ensure {@link NetworkRegistrationState#isRoaming()} does not throw any
+     * exception.
+     */
+    @Test
+    public void testNetworkRegistrationStateIsRoaming() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        // get NetworkRegistration object
+        NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+                .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+                        AccessNetworkConstants.TransportType.WWAN);
+        assertThat(nwReg).isNotNull();
+        nwReg.isRoaming();
+    }
+
+    /**
+     * Basic test to ensure {@link NetworkRegistrationState#getRoamingType()} ()} does not throw any
+     * exception and returns valid result
+     * @see ServiceState.RoamingType
+     */
+    @Test
+    public void testNetworkRegistrationStateGetRoamingType() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        // get NetworkRegistration object for voice
+        NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+                .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+                        AccessNetworkConstants.TransportType.WWAN);
+        assertNotNull(nwReg);
+        assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
+
+        // getNetworkRegistration object for data
+        // get NetworkRegistration object for voice
+        nwReg = mTelephonyManager.getServiceState()
+                .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+                        AccessNetworkConstants.TransportType.WWAN);
+        assertThat(nwReg).isNotNull();
+        assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
+    }
+
+    /**
+     * Basic test to ensure {@link NetworkRegistrationState#getAccessNetworkTechnology()} not
+     * throw any exception and returns valid result
+     * @see TelephonyManager.NetworkType
+     */
+    @Test
+    public void testNetworkRegistationStateGetAccessNetworkTechnology() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        // get NetworkRegistration object for voice
+        NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+                .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+                        AccessNetworkConstants.TransportType.WWAN);
+        assertThat(nwReg).isNotNull();
+        assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
+
+        // get NetworkRegistation object for data
+        nwReg = mTelephonyManager.getServiceState()
+                .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+                        AccessNetworkConstants.TransportType.WWAN);
+        assertThat(nwReg).isNotNull();
+        assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
+    }
+
+
+    /**
      * Tests that the device properly reports either a valid MEID or null.
      */
     @Test
@@ -744,4 +1018,12 @@
         boolean isEmergencyNumber = mTelephonyManager.isCurrentPotentialEmergencyNumber("911");
         // TODO enhance it later
     }
+
+    public static void waitForMs(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+            Log.d(TAG, "InterruptedException while waiting: " + e);
+        }
+    }
 }
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyUtils.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/TelephonyUtils.java
rename to tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/VisualVoicemailServiceTest.java b/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/VisualVoicemailServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/DownloadRequestTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/DownloadRequestTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/DownloadRequestTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/DownloadRequestTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/ServiceInfoTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/ServiceInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/ServiceInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/ServiceInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/SomeArgs.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/SomeArgs.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/SomeArgs.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/SomeArgs.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccInfoTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccManagerTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccResolutionActivity.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/GsmCellLocationTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/GsmCellLocationTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/GsmCellLocationTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/GsmCellLocationTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
diff --git a/tests/tests/text/Android.mk b/tests/tests/telephony/sdk28/Android.mk
similarity index 66%
copy from tests/tests/text/Android.mk
copy to tests/tests/telephony/sdk28/Android.mk
index ffa5f9eb..36e30fd 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/telephony/sdk28/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2015 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.
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -21,24 +22,19 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
-    compatibility-device-util \
-    ctsdeviceutillegacy \
+LOCAL_STATIC_JAVA_LIBRARIES := \
     ctstestrunner \
-    android-support-test \
-    mockito-target-minus-junit4 \
-    ub-uiautomator
+    compatibility-device-util
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsTextTestCases
+LOCAL_PACKAGE_NAME := CtsTelephonySdk28TestCases
+LOCAL_SDK_VERSION := 28
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
+LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
+LOCAL_JAVA_LIBRARIES += android.test.base.stubs
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telephony/sdk28/AndroidManifest.xml b/tests/tests/telephony/sdk28/AndroidManifest.xml
new file mode 100644
index 0000000..2f37696
--- /dev/null
+++ b/tests/tests/telephony/sdk28/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.telephony.sdk28.cts">
+    <uses-sdk android:targetSdkVersion="28"
+              android:minSdkVersion="28"
+              android:maxSdkVersion="28" />
+
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.telephony.sdk28.cts">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/telephony/sdk28/AndroidTest.xml
similarity index 60%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/telephony/sdk28/AndroidTest.xml
index 907fb2d..ab37882 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/telephony/sdk28/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2015 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.
@@ -13,16 +13,21 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS Telephony test cases">
     <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="component" value="telecom" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+    <option name="not-shardable" value="true" />
+    <target_preparer class="android.telephony.cts.preconditions.TelephonyPreparer">
+        <option name="apk" value="CtsTelephonyPreparerApp.apk" />
+        <option name="package" value="android.telephony.cts.preconditions.app" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+        <option name="test-file-name" value="CtsTelephonySdk28TestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.libcore.cts.coreplatformapi" />
-        <option name="runtime-hint" value="1m"/>
+        <option name="package" value="android.telephony.sdk28.cts" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java b/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java
new file mode 100644
index 0000000..aebeeda
--- /dev/null
+++ b/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.telephony.sdk28.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.os.Parcel;
+import android.telephony.CellInfo;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+import java.util.List;
+import java.util.Objects;
+
+public class CellInfoTest extends AndroidTestCase {
+    private static final String TAG = "CellInfoTest";
+
+    private static final int MAX_WAIT_SECONDS = 15;
+    private static final int POLL_INTERVAL_MILLIS = 1000;
+
+    private TelephonyManager mTm;
+    private PackageManager mPm;
+
+    private boolean isCamped() {
+        ServiceState ss = mTm.getServiceState();
+        if (ss == null) return false;
+        return (ss.getState() == ServiceState.STATE_IN_SERVICE
+                || ss.getState() == ServiceState.STATE_EMERGENCY_ONLY);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTm = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mPm = getContext().getPackageManager();
+    }
+
+    public void testCellInfoSdk28() {
+        if (!mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+            return;
+        }
+
+        if (!isCamped()) fail("Device is not camped to a cell");
+
+        List<CellInfo> cellInfo = mTm.getAllCellInfo();
+
+        // getAllCellInfo should never return null, and there should be at least one entry.
+        assertNotNull("TelephonyManager.getAllCellInfo() returned NULL CellInfo", cellInfo);
+        assertFalse("TelephonyManager.getAllCellInfo() returned an empty list", cellInfo.isEmpty());
+
+        final long initialTime = cellInfo.get(0).getTimeStamp();
+
+        for(int i = 0; i < MAX_WAIT_SECONDS; i++) {
+            try {
+                Thread.sleep(POLL_INTERVAL_MILLIS); // 1 second
+            } catch (InterruptedException ie) {
+                fail("Thread was interrupted");
+            }
+            List<CellInfo> newCellInfo = mTm.getAllCellInfo();
+            assertNotNull("TelephonyManager.getAllCellInfo() returned NULL CellInfo", newCellInfo);
+            assertFalse("TelephonyManager.getAllCellInfo() returned an empty list",
+                    newCellInfo.isEmpty());
+            // Test that new CellInfo has been retrieved from the modem
+            if (newCellInfo.get(0).getTimeStamp() != initialTime) return;
+        }
+        fail("CellInfo failed to update after " + MAX_WAIT_SECONDS + " seconds.");
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
deleted file mode 100644
index 7745497..0000000
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) 2009 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.telephony.cts;
-
-import android.content.Context;
-import android.os.Looper;
-import android.telephony.CellInfo;
-import android.telephony.CellLocation;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.net.ConnectivityManager;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.compatibility.common.util.TestThread;
-
-import java.util.List;
-
-public class PhoneStateListenerTest extends  AndroidTestCase{
-
-    public static final long WAIT_TIME = 1000;
-
-    private boolean mOnCallForwardingIndicatorChangedCalled;
-    private boolean mOnCallStateChangedCalled;
-    private boolean mOnCellLocationChangedCalled;
-    private boolean mOnUserMobileDataStateChanged;
-    private boolean mOnDataActivityCalled;
-    private boolean mOnDataConnectionStateChangedCalled;
-    private boolean mOnDataConnectionStateChangedWithNetworkTypeCalled;
-    private boolean mOnMessageWaitingIndicatorChangedCalled;
-    private boolean mOnCellInfoChangedCalled;
-    private boolean mOnServiceStateChangedCalled;
-    private boolean mOnSignalStrengthChangedCalled;
-    private SignalStrength mSignalStrength;
-    private TelephonyManager mTelephonyManager;
-    private PhoneStateListener mListener;
-    private final Object mLock = new Object();
-    private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
-    private static ConnectivityManager mCm;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTelephonyManager =
-                (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
-        mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        if (mListener != null) {
-            // unregister the listener
-            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
-        }
-    }
-
-    public void testPhoneStateListener() {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        Looper.prepare();
-        new PhoneStateListener();
-    }
-
-    /*
-     * The tests below rely on the framework to immediately call the installed listener upon
-     * registration. There is no simple way to emulate state changes for testing the listeners.
-     */
-
-    public void testOnServiceStateChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onServiceStateChanged(ServiceState serviceState) {
-                        synchronized(mLock) {
-                            mOnServiceStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnServiceStateChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnServiceStateChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnServiceStateChangedCalled);
-    }
-
-    public void testOnSignalStrengthChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthChanged(int asu) {
-                        synchronized(mLock) {
-                            mOnSignalStrengthChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnSignalStrengthChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnSignalStrengthChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnSignalStrengthChangedCalled);
-    }
-
-    public void testOnSignalStrengthsChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-                        synchronized(mLock) {
-                            mSignalStrength = signalStrength;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
-
-                Looper.loop();
-            }
-        });
-
-        assertTrue(mSignalStrength == null);
-        t.start();
-
-        synchronized (mLock) {
-            while(mSignalStrength == null) {
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mSignalStrength != null);
-
-        // Call SignalStrength methods to make sure they do not throw any exceptions
-        mSignalStrength.getCdmaDbm();
-        mSignalStrength.getCdmaEcio();
-        mSignalStrength.getEvdoDbm();
-        mSignalStrength.getEvdoEcio();
-        mSignalStrength.getEvdoSnr();
-        mSignalStrength.getGsmBitErrorRate();
-        mSignalStrength.getGsmSignalStrength();
-        mSignalStrength.isGsm();
-        mSignalStrength.getLevel();
-    }
-
-    public void testOnMessageWaitingIndicatorChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onMessageWaitingIndicatorChanged(boolean mwi) {
-                        synchronized(mLock) {
-                            mOnMessageWaitingIndicatorChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnMessageWaitingIndicatorChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnMessageWaitingIndicatorChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnMessageWaitingIndicatorChangedCalled);
-    }
-
-    public void testOnCallForwardingIndicatorChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            @Override
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCallForwardingIndicatorChanged(boolean cfi) {
-                        synchronized(mLock) {
-                            mOnCallForwardingIndicatorChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnCallForwardingIndicatorChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnCallForwardingIndicatorChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnCallForwardingIndicatorChangedCalled);
-    }
-
-    public void testOnCellLocationChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCellLocationChanged(CellLocation location) {
-                        synchronized(mLock) {
-                            mOnCellLocationChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnCellLocationChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnCellLocationChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnCellLocationChangedCalled);
-    }
-
-    public void testOnCallStateChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCallStateChanged(int state, String incomingNumber) {
-                        synchronized(mLock) {
-                            mOnCallStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnCallStateChangedCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnCallStateChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnCallStateChangedCalled);
-    }
-
-    public void testOnDataConnectionStateChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onDataConnectionStateChanged(int state) {
-                        synchronized(mLock) {
-                            mOnDataConnectionStateChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                    @Override
-                    public void onDataConnectionStateChanged(int state, int networkType) {
-                        synchronized(mLock) {
-                            mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnDataConnectionStateChangedCalled);
-        assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnDataConnectionStateChangedCalled ||
-                    !mOnDataConnectionStateChangedWithNetworkTypeCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnDataConnectionStateChangedCalled);
-        assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
-    }
-
-    public void testOnDataActivity() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onDataActivity(int direction) {
-                        synchronized(mLock) {
-                            mOnDataActivityCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnDataActivityCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnDataActivityCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnDataActivityCalled);
-    }
-
-    public void testOnCellInfoChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCellInfoChanged(List<CellInfo> cellInfo) {
-                        synchronized(mLock) {
-                            mOnCellInfoChangedCalled = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnDataActivityCalled);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnCellInfoChangedCalled){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnCellInfoChangedCalled);
-    }
-
-    public void testOnUserMobileDataStateChanged() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
-            return;
-        }
-
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onUserMobileDataStateChanged(boolean state) {
-                        synchronized(mLock) {
-                            mOnUserMobileDataStateChanged = true;
-                            mLock.notify();
-                        }
-                    }
-                };
-                mTelephonyManager.listen(
-                        mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
-
-                Looper.loop();
-            }
-        });
-
-        assertFalse(mOnUserMobileDataStateChanged);
-        t.start();
-
-        synchronized (mLock) {
-            while(!mOnUserMobileDataStateChanged){
-                mLock.wait();
-            }
-        }
-        t.checkException();
-        assertTrue(mOnUserMobileDataStateChanged);
-    }
-}
diff --git a/tests/tests/text/Android.mk b/tests/tests/telephony4/Android.mk
similarity index 63%
copy from tests/tests/text/Android.mk
copy to tests/tests/telephony4/Android.mk
index ffa5f9eb..293224f 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/telephony4/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -21,24 +22,27 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
+LOCAL_JAVA_LIBRARIES := telephony-common \
+    android.test.runner.stubs \
+    android.test.base.stubs
 
-LOCAL_STATIC_JAVA_LIBRARIES += \
-    compatibility-device-util \
-    ctsdeviceutillegacy \
+LOCAL_STATIC_JAVA_LIBRARIES := \
     ctstestrunner \
-    android-support-test \
-    mockito-target-minus-junit4 \
-    ub-uiautomator
+    compatibility-device-util \
+    truth-prebuilt
+
+LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsTextTestCases
+LOCAL_PACKAGE_NAME := CtsSimRestrictedApisTestCases
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
+LOCAL_CERTIFICATE := cts/tests/tests/telephony4/certs/android_telephony_cts_testkey
+
 
 include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/telephony4/AndroidManifest.xml b/tests/tests/telephony4/AndroidManifest.xml
new file mode 100644
index 0000000..b292bb1
--- /dev/null
+++ b/tests/tests/telephony4/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.telephony4.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.telephony4.cts"
+                     android:label="CTS tests of android.telephony4">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/telephony4/AndroidTest.xml
similarity index 69%
rename from tests/libcore/coreplatformapi/AndroidTest.xml
rename to tests/tests/telephony4/AndroidTest.xml
index 907fb2d..636ecbb1 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/telephony4/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -13,16 +13,15 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS Telephony4 test cases">
     <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="component" value="telecom" />
+    <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+        <option name="test-file-name" value="CtsSimRestrictedApisTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.libcore.cts.coreplatformapi" />
-        <option name="runtime-hint" value="1m"/>
-        <option name="hidden-api-checks" value="false"/>
+        <option name="package" value="android.telephony4.cts" />
     </test>
 </configuration>
diff --git a/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8 b/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8
new file mode 100644
index 0000000..f83d5ed
--- /dev/null
+++ b/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8
Binary files differ
diff --git a/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem b/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem
new file mode 100644
index 0000000..29ffd6a
--- /dev/null
+++ b/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIF9TCCA92gAwIBAgIVAIja2SQYIM1wfIrwgObEUdBk/MfkMA0GCSqGSIb3DQEBCwUAMIGKMQsw
+CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU
+MBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxJjAkBgNVBAMMHWFuZHJvaWRf
+dGVsZXBob255X2N0c190ZXN0a2V5MB4XDTE5MDExMTE5MzMwM1oXDTQ5MDExMTE5MzMwM1owgYox
+CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3
+MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEmMCQGA1UEAwwdYW5kcm9p
+ZF90ZWxlcGhvbnlfY3RzX3Rlc3RrZXkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9
+IXCTl7o3J6gy5YleQRFm5Xahth5hwpC7b/cfZiSW25AqNLZRcZJZDwYiJIpqOu773Hr5fEZMV5c1
+tYivwdwKnoGlWiqrpvwafIQxsAPtKoiSsB6r6Zx4hZBDzf5M+PRi3ieUrPrwaiGeVy1n4nPhcpHy
+bzE2G+ZkfzxRYRmmObi8+UC4lkI2dL1Y17hjNmWpeJrfhvl67K2gMmAtwjW2UxhyOcACg8Mya1eA
+VyqQgiEfMb52FK1opshHnGpIcLjY7UT1IesOZpWu3OWqiOw/KCU+nJaEemYFYceGR14RGfKk9r1N
+hcRhZLXPfZHr9TPsJ/O/oKrF3Q+TxoUJIhQ3lcYREftrqMZNDUUANENnfd1Bviu2atschG5Ohchk
+MiuKDadMl++LOkfGjoTikQXUHGxb4GIfgLJDmkp6+Andc2iZ2pRPm6zQmHXWmcwtz3RvyGtK0oYJ
+xwpVy0InE/Ao1sH8LrYvBPWKDVHbG2v+ydYYrx39ScBLgXQ4gxmTNU8+YX3zXVaGWMPuVP2GfyBl
+O+fl27RZO/XZlC28TQEMAvytSyeTs4blubRlLgcf9wAv774a797g7uSRSZ+8aqumatPrtZnhBojU
+2U4zuQilE5JGIIvM5ZGWUNMMkY5bB4bnw36oSK7kup8dyLlT7Jgfpc5RuzYPKzU+OcH/k0SeZwID
+AQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBR4+8+XqYU6x7dqy/fwqz5eG2TQIjAfBgNV
+HSMEGDAWgBR4+8+XqYU6x7dqy/fwqz5eG2TQIjANBgkqhkiG9w0BAQsFAAOCAgEAaxTiY0j+Xgig
+WnsfqJRCV7Qn6LFhCyS2zc96g+m0CkiPLW83BFkVND9JaAUVw3GIUKDEtZkUy3v5L4//QmfdYIbH
+IBX5d/GJAVkH4MRFb47Mr2qu6t33eNiDaRzJe5WIQ+3qI1P0/2ihqKOAEC8OSWQWzY8eWB9O4vKp
+U/0JENOcSTfthce7dDhCCqw3P0Xmo9xW1x9YqcAPzNcQE7Lm68MeOB9esoTlIFS7R9tRp17pBU8Y
+Lw9WSRFy6jBYX1Wf83M96+WPNQensLymnXMDuwJhoNV5MnGMkqsASfkzZwLxcLRKlt4gJ4gmmPlM
+mIeJCcMvUJIMOlYcNEiBF4i4CkzA/ThxPRXSCZdQKjzM5YG7Sj3uEJTYgDq+50k/nKnhqKymZhQN
+pXtax3/2ivonWfNaWWIYBEY3aRQTb3IwTRjM1ib6Aj4sIjATzP0vowmYoQf/iv5HKYyndyRcy4zR
+LeOUbU5Hk0Rhc896eOFshwuB8VQ/6kiIPWN4VRNXn/hjT+p5y+ww8IM1crLV+ftdRDhDKbgxNfo1
+R1uhZgRryzWBmFEz6wSKDctdVeZ087e3pfze+V3/hrT2gevoYtcMHT7+qmNssnDbUinXJicQAQBn
+Wl2lx+PwyRnQ1dAozjcpytqXNmRF/881E2MvtdAN5Y4F5d0fh32Yi455xQ5UNb0=
+-----END CERTIFICATE-----
+
diff --git a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
similarity index 88%
rename from tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
rename to tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
index b15a4e8..c1189a2 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
+++ b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.telephony.cts;
+package android.telephony4.cts;
 
 import android.content.Context;
 import android.telephony.SmsManager;
@@ -59,7 +59,7 @@
     public void testSetLine1NumberForDisplay() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().setLine1NumberForDisplay("", "");
+                mTelephonyManager.setLine1NumberForDisplay("", "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -74,7 +74,7 @@
     public void testSetLine1NumberForDisplay2() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().setLine1NumberForDisplay(0, "", "");
+                mTelephonyManager.setLine1NumberForDisplay(0, "", "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -89,7 +89,7 @@
     public void testIccOpenLogicalChannel() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().iccOpenLogicalChannel("");
+                mTelephonyManager.iccOpenLogicalChannel("");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -104,7 +104,7 @@
     public void testIccCloseLogicalChannel() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().iccCloseLogicalChannel(0);
+                mTelephonyManager.iccCloseLogicalChannel(0);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -119,7 +119,7 @@
     public void testIccTransmitApduLogicalChannel() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
+                mTelephonyManager.iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -134,7 +134,7 @@
     public void testIccTransmitApduBasicChannel() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
+                mTelephonyManager.iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -149,7 +149,7 @@
     public void testSendEnvelopeWithStatus() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().sendEnvelopeWithStatus("");
+                mTelephonyManager.sendEnvelopeWithStatus("");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -163,7 +163,7 @@
     public void testNvReadItem() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().nvReadItem(0);
+                mTelephonyManager.nvReadItem(0);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -177,7 +177,7 @@
     public void testNvWriteItem() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().nvWriteItem(0, "");
+                mTelephonyManager.nvWriteItem(0, "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -191,7 +191,7 @@
     public void testNvWriteCdmaPrl() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().nvWriteCdmaPrl(null);
+                mTelephonyManager.nvWriteCdmaPrl(null);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -205,7 +205,7 @@
     public void testNvResetConfig() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().nvResetConfig(0);
+                mTelephonyManager.nvResetConfig(1);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -220,7 +220,7 @@
     public void testGetPreferredNetworkType() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().getPreferredNetworkType(0);
+                mTelephonyManager.getPreferredNetworkType(0);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -235,7 +235,7 @@
     public void testSetPreferredNetworkTypeToGlobal() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().setPreferredNetworkTypeToGlobal();
+                mTelephonyManager.setPreferredNetworkTypeToGlobal();
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -246,7 +246,7 @@
      * Tests that the test apk doesn't have carrier previliges.
      */
     public void testHasCarrierPrivileges() {
-        if (TelephonyManager.getDefault().hasCarrierPrivileges()) {
+        if (mTelephonyManager.hasCarrierPrivileges()) {
             fail("App unexpectedly has carrier privileges");
         }
     }
@@ -259,7 +259,7 @@
     public void testSetOperatorBrandOverride() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().setOperatorBrandOverride("");
+                mTelephonyManager.setOperatorBrandOverride("");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
@@ -274,7 +274,7 @@
     public void testGetIccAuthentication() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+                mTelephonyManager.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
                         TelephonyManager.AUTHTYPE_EAP_AKA, "");
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
new file mode 100644
index 0000000..e6ec35a
--- /dev/null
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 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.telephonyprovider.cts;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.telephonyprovider.cts.DefaultSmsAppHelper.setDefaultSmsApp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.annotation.Nullable;
+
+public class MmsPartTest {
+    private ContentResolver mContentResolver;
+
+    /**
+     * Parts must be inserted in relation to a message, this message ID is used for inserting a
+     * part when the message ID is not important in relation to the current test.
+     */
+    private static final String TEST_MESSAGE_ID = "100";
+
+    @Before
+    public void setupTestEnvironment() {
+        cleanup();
+        mContentResolver = getInstrumentation().getContext().getContentResolver();
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        ContentResolver contentResolver =
+                InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
+
+        setDefaultSmsApp(true);
+        contentResolver.delete(Telephony.Mms.Part.CONTENT_URI, null, null);
+        setDefaultSmsApp(false);
+    }
+
+    @Test
+    public void testMmsPartInsert_cannotInsertPartWithDataColumn() {
+        setDefaultSmsApp(true);
+
+        ContentValues values = new ContentValues();
+        values.put(Telephony.Mms.Part._DATA, "/dev/urandom");
+        values.put(Telephony.Mms.Part.NAME, "testMmsPartInsert_cannotInsertPartWithDataColumn");
+
+        Uri uri = insertTestMmsPartWithValues(values);
+        assertThat(uri).isNull();
+    }
+
+    @Test
+    public void testMmsPartInsert_canInsertPartWithoutDataColumn() {
+        setDefaultSmsApp(true);
+
+        String name = "testMmsInsert_canInsertPartWithoutDataColumn";
+
+        Uri uri = insertTestMmsPartWithName(name);
+        assertThatMmsPartInsertSucceeded(uri, name);
+    }
+
+    @Test
+    public void testMmsPart_deletedPartIdsAreNotReused() {
+        setDefaultSmsApp(true);
+
+        long id1 = insertAndVerifyMmsPartReturningId("testMmsPart_deletedPartIdsAreNotReused_1");
+
+        deletePartById(id1);
+
+        long id2 = insertAndVerifyMmsPartReturningId("testMmsPart_deletedPartIdsAreNotReused_2");
+
+        assertThat(id2).isGreaterThan(id1);
+    }
+
+    private long insertAndVerifyMmsPartReturningId(String name) {
+        Uri uri = insertTestMmsPartWithName(name);
+        assertThatMmsPartInsertSucceeded(uri, name);
+        return Long.parseLong(uri.getLastPathSegment());
+    }
+
+    private void deletePartById(long partId) {
+        Uri uri = Uri.withAppendedPath(Telephony.Mms.Part.CONTENT_URI, Long.toString(partId));
+        int deletedRows = mContentResolver.delete(uri, null, null);
+        assertThat(deletedRows).isEqualTo(1);
+    }
+
+    private Uri insertTestMmsPartWithName(String name) {
+        ContentValues values = new ContentValues();
+        values.put(Telephony.Mms.Part.NAME, name);
+        return insertTestMmsPartWithValues(values);
+    }
+
+    private Uri insertTestMmsPartWithValues(ContentValues values) {
+        Uri insertUri = Telephony.Mms.CONTENT_URI.buildUpon()
+                .appendPath(TEST_MESSAGE_ID)
+                .appendPath("part")
+                .build();
+
+        Uri uri = mContentResolver.insert(insertUri, values);
+        return uri;
+    }
+
+    private void assertThatMmsPartInsertSucceeded(@Nullable Uri uriReturnedFromInsert,
+            String nameOfAttemptedInsert) {
+        assertThat(uriReturnedFromInsert).isNotNull();
+
+        Cursor cursor = mContentResolver.query(uriReturnedFromInsert, null, null, null);
+
+        assertThat(cursor.getCount()).isEqualTo(1);
+
+        cursor.moveToNext();
+        String actualName = cursor.getString(cursor.getColumnIndex(Telephony.Mms.Part.NAME));
+        assertThat(actualName).isEqualTo(nameOfAttemptedInsert);
+    }
+
+}
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
index e48be31..4922864 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
@@ -29,7 +29,6 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
-import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
@@ -159,16 +158,6 @@
         assertThatMmsInsertSucceeded(uri, expectedSubject);
     }
 
-    @Test
-    public void testMmsInsert_cannotInsertPartWithDataColumn() {
-        setDefaultSmsApp(true);
-        Uri uri = Uri.parse("content://mms/100/part");
-        ContentValues values = new ContentValues();
-        values.put("_data", "/dev/urandom");
-        Uri uri2 = mContentResolver.insert(uri, values);
-        assertThat(uri2).isNull();
-    }
-
     /**
      * Asserts that a URI returned from an MMS insert operation represents a failed insert.
      *
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java
new file mode 100644
index 0000000..505ab82
--- /dev/null
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java
@@ -0,0 +1,78 @@
+package android.telephonyprovider.cts;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.telephonyprovider.cts.DefaultSmsAppHelper.setDefaultSmsApp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class ThreadsTest {
+    private Context mContext;
+    private ContentResolver mContentResolver;
+
+    @Before
+    public void setupTestEnvironment() {
+        cleanup();
+        mContext = getInstrumentation().getContext();
+        mContentResolver = mContext.getContentResolver();
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        ContentResolver contentResolver =
+                InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
+
+        setDefaultSmsApp(true);
+        contentResolver.delete(Telephony.Threads.CONTENT_URI, null, null);
+        setDefaultSmsApp(false);
+    }
+
+    @Test
+    public void testThreadDeletion_doNotReuseThreadIdsFromEmptyThreads() {
+        setDefaultSmsApp(true);
+
+        String destination1 = "+19998880001";
+        String destination2 = "+19998880002";
+
+        long threadId1 = Telephony.Threads.getOrCreateThreadId(mContext, destination1);
+
+        Uri inboxUri = saveToTelephony(threadId1, destination1, "testThreadDeletion body");
+
+        // The URI returned by the insert operation points to the message ID in the inbox. Though
+        // this is a valid ID for queries, the SMS provider does not handle it for delete
+        // operations. This takes the ID off the end of the URI and creates a URI pointing at that
+        // row from the root of the SMS provider.
+        Uri rootUri =
+                Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, inboxUri.getLastPathSegment());
+
+        int deletedCount = mContentResolver.delete(rootUri, null, null);
+
+        assertThat(deletedCount).isEqualTo(1);
+
+        long threadId2 = Telephony.Threads.getOrCreateThreadId(mContext, destination2);
+
+        assertThat(threadId2).isGreaterThan(threadId1);
+    }
+
+    private Uri saveToTelephony(long threadId, String address, String body) {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Telephony.Sms.THREAD_ID, threadId);
+        contentValues.put(Telephony.Sms.ADDRESS, address);
+        contentValues.put(Telephony.Sms.BODY, body);
+
+        return mContext.getContentResolver().insert(Telephony.Sms.Inbox.CONTENT_URI, contentValues);
+    }
+}
+
diff --git a/tests/tests/text/Android.bp b/tests/tests/text/Android.bp
new file mode 100644
index 0000000..8670814
--- /dev/null
+++ b/tests/tests/text/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2008 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.
+
+android_test {
+    name: "CtsTextTestCases",
+    defaults: ["cts_defaults"],
+    sdk_version: "test_current",
+
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+
+    static_libs: [
+        "compatibility-device-util",
+        "ctsdeviceutillegacy",
+        "ctstestrunner",
+        "mockito-target-minus-junit4",
+        "android-support-test",
+        "ub-uiautomator",
+    ],
+
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+        "cts_instant",
+    ],
+}
diff --git a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
index 9a7e39a..7c7694e 100644
--- a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
+++ b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
@@ -21,10 +21,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
 
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
@@ -46,6 +42,7 @@
 import org.mockito.ArgumentMatcher;
 
 import java.util.Locale;
+import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -464,23 +461,15 @@
         }
     }
 
-    public class MyUrlSpanFactory extends Linkify.UrlSpanFactory {
-        @Override
-        public URLSpan create(String url) {
-            return new MyUrlSpan(url);
-        }
-    }
-
     @Test
     public void testAddLinks_UrlSpanFactory_withSpannable() {
         final String text = "a https://android.com a +1 123 456 7878 a android@android.com a";
         final Spannable spannable = new SpannableString(text);
         final int mask = Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES;
-        final Linkify.UrlSpanFactory urlSpanFactory = spy(new MyUrlSpanFactory());
+        final Function<String, URLSpan> spanFactory = (String string) -> new MyUrlSpan(string);
 
-        Linkify.addLinks(spannable, mask, urlSpanFactory);
+        Linkify.addLinks(spannable, mask, spanFactory);
 
-        verify(urlSpanFactory, times(3)).create(anyString());
         final MyUrlSpan[] myUrlSpans = spannable.getSpans(0, spannable.length(), MyUrlSpan.class);
         assertNotNull(myUrlSpans);
         assertEquals(3, myUrlSpans.length);
@@ -496,12 +485,10 @@
     public void testAddLinks_UrlSpanFactory_withSpannableAndFilter() {
         final String text = "google.pattern, test:AZ0101.pattern";
         final SpannableString spannable = new SpannableString(text);
-        final Linkify.UrlSpanFactory urlSpanFactory = spy(new MyUrlSpanFactory());
+        final Function<String, URLSpan> spanFactory = (String string) -> new MyUrlSpan(string);
 
         Linkify.addLinks(spannable, LINKIFY_TEST_PATTERN, "test:", null /*schemes*/,
-                null /*matchFilter*/, null /*transformFilter*/, urlSpanFactory);
-
-        verify(urlSpanFactory, times(2)).create(anyString());
+                null /*matchFilter*/, null /*transformFilter*/, spanFactory);
 
         final MyUrlSpan[] myUrlSpans = spannable.getSpans(0, spannable.length(), MyUrlSpan.class);
         assertNotNull(myUrlSpans);
@@ -513,13 +500,6 @@
         assertArrayEquals(myUrlSpans, urlSpans);
     }
 
-    @Test
-    public void testDefaultUrlSpanFactory() {
-        URLSpan urlSpan = new Linkify.UrlSpanFactory().create("some url");
-        assertNotNull(urlSpan);
-        assertEquals("some url", urlSpan.getURL());
-    }
-
     // WEB_URLS Related Tests
 
     @Test
diff --git a/tests/tests/tools/processors/view_inspector/Android.bp b/tests/tests/tools/processors/view_inspector/Android.bp
new file mode 100644
index 0000000..bcebde1
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/Android.bp
@@ -0,0 +1,34 @@
+// Copyright 2019 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.
+
+android_test {
+    name: "CtsViewInspectorAnnotationProcessorTestCases",
+    sdk_version: "test_current",
+
+    srcs: ["src/**/*.java"],
+
+    plugins: ["view-inspector-annotation-processor"],
+
+    static_libs: [
+        "android-support-test",
+        "compatibility-device-util",
+        "ctstestrunner",
+    ],
+
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ]
+}
diff --git a/tests/tests/tools/processors/view_inspector/AndroidManifest.xml b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
new file mode 100644
index 0000000..e6574d7
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.processor.view.inspector.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.processor.view.inspector.cts"
+                     android:label="CTS tests of android.processor.view.inspector">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
similarity index 69%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/tools/processors/view_inspector/AndroidTest.xml
index 907fb2d..dab96b2 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright 2019 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.
@@ -13,16 +13,18 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS view inspector annotation processor test cases">
+
     <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+        <option name="test-file-name" value="CtsViewInspectorAnnotationProcessorTestCases.apk" />
     </target_preparer>
+
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.libcore.cts.coreplatformapi" />
-        <option name="runtime-hint" value="1m"/>
-        <option name="hidden-api-checks" value="false"/>
+        <option name="package" value="android.processor.view.inspector.cts" />
+        <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
new file mode 100644
index 0000000..4088797
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import android.R;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.inspector.InspectableNodeName;
+import android.view.inspector.InspectableProperty;
+import android.view.inspector.InspectableProperty.ValueType;
+import android.view.inspector.InspectionCompanion;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorLong;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Objects;
+import java.util.Random;
+
+/**
+ * Behavioral tests for {@link android.processor.view.inspector.PlatformInspectableProcessor}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PlatformInspectableProcessorTest {
+    private Random mRandom;
+    private TestPropertyMapper mPropertyMapper;
+    private TestPropertyReader mPropertyReader;
+
+    @Before
+    public void setup() {
+        mRandom = new Random();
+        mPropertyMapper = new TestPropertyMapper();
+        mPropertyReader = new TestPropertyReader(mPropertyMapper);
+    }
+
+    @InspectableNodeName("my_node")
+    class NodeNameInspectable {
+    }
+
+
+    @Test
+    public void testNodeName() {
+        assertEquals("my_node", loadCompanion(NodeNameInspectable.class).getNodeName());
+        assertNull(loadCompanion(IntPropertyInspectable.class).getNodeName());
+    }
+
+    class IntPropertyInspectable {
+        private final int mValue;
+
+        IntPropertyInspectable(Random seed) {
+            mValue = seed.nextInt();
+        }
+
+        @InspectableProperty
+        public int getValue() {
+            return mValue;
+        }
+    }
+
+    @Test
+    public void testMapAndReadInt() {
+        IntPropertyInspectable inspectable = new IntPropertyInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getValue(), mPropertyReader.get("value"));
+    }
+
+    @Test
+    public void testInferredAttributeId() {
+        loadCompanion(IntPropertyInspectable.class).mapProperties(mPropertyMapper);
+        assertEquals(R.attr.value, mPropertyMapper.getAttributeId("value"));
+    }
+
+    @Test(expected = InspectionCompanion.UninitializedPropertyMapException.class)
+    public void testUninitializedPropertyMap() {
+        IntPropertyInspectable inspectable = new IntPropertyInspectable(mRandom);
+        loadCompanion(IntPropertyInspectable.class).readProperties(inspectable, mPropertyReader);
+    }
+
+    class NamedPropertyInspectable {
+        private final int mValue;
+
+        NamedPropertyInspectable(Random seed) {
+            mValue = seed.nextInt();
+        }
+
+        @InspectableProperty(name = "myNamedValue", hasAttributeId = false)
+        public int getValue() {
+            return mValue;
+        }
+    }
+
+    @Test
+    public void testNamedProperty() {
+        NamedPropertyInspectable inspectable = new NamedPropertyInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(0, mPropertyMapper.getId("value"));
+        assertEquals(inspectable.getValue(), mPropertyReader.get("myNamedValue"));
+    }
+
+    class HasAttributeIdFalseInspectable {
+        @InspectableProperty(hasAttributeId = false)
+        public int getValue() {
+            return 0;
+        }
+    }
+
+    @Test
+    public void testHasAttributeIdFalse() {
+        loadCompanion(HasAttributeIdFalseInspectable.class).mapProperties(mPropertyMapper);
+        assertEquals(Resources.ID_NULL, mPropertyMapper.getAttributeId("value"));
+    }
+
+    class AttributeIdEqualsInspectable {
+        @InspectableProperty(attributeId = 0xdecafbad)
+        public int getValue() {
+            return 0;
+        }
+    }
+
+    @Test
+    public void testAttributeIdEquals() {
+        loadCompanion(AttributeIdEqualsInspectable.class).mapProperties(mPropertyMapper);
+        assertEquals(0xdecafbad, mPropertyMapper.getAttributeId("value"));
+    }
+
+    class InferredPropertyNameInspectable {
+        private final int mValueA;
+        private final int mValueB;
+        private final int mValueC;
+
+        InferredPropertyNameInspectable(Random seed) {
+            mValueA = seed.nextInt();
+            mValueB = seed.nextInt();
+            mValueC = seed.nextInt();
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public int getValueA() {
+            return mValueA;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public int isValueB() {
+            return mValueB;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public int obtainValueC() {
+            return mValueC;
+        }
+    }
+
+    @Test
+    public void testInferredPropertyName() {
+        InferredPropertyNameInspectable inspectable = new InferredPropertyNameInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getValueA(), mPropertyReader.get("valueA"));
+        assertEquals(inspectable.isValueB(), mPropertyReader.get("isValueB"));
+        assertEquals(inspectable.obtainValueC(), mPropertyReader.get("obtainValueC"));
+    }
+
+    class InferredBooleanNameInspectable {
+        private final boolean mValueA;
+        private final boolean mValueB;
+        private final boolean mValueC;
+
+        InferredBooleanNameInspectable(Random seed) {
+            mValueA = seed.nextBoolean();
+            mValueB = seed.nextBoolean();
+            mValueC = seed.nextBoolean();
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public boolean getValueA() {
+            return mValueA;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public boolean isValueB() {
+            return mValueB;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public boolean obtainValueC() {
+            return mValueC;
+        }
+    }
+
+    @Test
+    public void testInferredBooleanName() {
+        InferredBooleanNameInspectable inspectable = new InferredBooleanNameInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getValueA(), mPropertyReader.get("valueA"));
+        assertEquals(inspectable.isValueB(), mPropertyReader.get("valueB"));
+        assertEquals(inspectable.obtainValueC(), mPropertyReader.get("obtainValueC"));
+    }
+
+    class ColorInspectable {
+        private final int mColorInt;
+        private final long mColorLong;
+
+        private final Color mColorObject;
+
+        ColorInspectable(Random seed) {
+            mColorInt = seed.nextInt();
+            mColorLong = Color.pack(seed.nextInt());
+            mColorObject = Color.valueOf(seed.nextInt());
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        @ColorInt
+        public int getColorInt() {
+            return mColorInt;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        @ColorLong
+        public long getColorLong() {
+            return mColorLong;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public Color getColorObject() {
+            return mColorObject;
+        }
+    }
+
+    @Test
+    public void testColorTypeInference() {
+        ColorInspectable inspectable = new ColorInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getColorInt(), mPropertyReader.get("colorInt"));
+        assertEquals(inspectable.getColorLong(), mPropertyReader.get("colorLong"));
+        assertEquals(inspectable.getColorObject(), mPropertyReader.get("colorObject"));
+        assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorInt"));
+        assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorLong"));
+        assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorObject"));
+    }
+
+    class ValueTypeInspectable {
+        private final int mColor;
+        private final int mGravity;
+        private final int mValue;
+
+        ValueTypeInspectable(Random seed) {
+            mColor = seed.nextInt();
+            mGravity = seed.nextInt();
+            mValue = seed.nextInt();
+        }
+
+        @InspectableProperty(valueType = ValueType.COLOR)
+        public int getColor() {
+            return mColor;
+        }
+
+        @InspectableProperty(valueType = ValueType.GRAVITY)
+        public int getGravity() {
+            return mGravity;
+        }
+
+        @InspectableProperty(valueType = ValueType.NONE)
+        @ColorInt
+        public int getValue() {
+            return mValue;
+        }
+    }
+
+    @Test
+    public void testValueTypeEquals() {
+        ValueTypeInspectable inspectable = new ValueTypeInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getColor(), mPropertyReader.get("color"));
+        assertEquals(inspectable.getGravity(), mPropertyReader.get("gravity"));
+        assertEquals(inspectable.getValue(), mPropertyReader.get("value"));
+        assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("color"));
+        assertEquals(ValueType.GRAVITY, mPropertyMapper.getValueType("gravity"));
+        assertEquals(ValueType.NONE, mPropertyMapper.getValueType("value"));
+    }
+
+    class PrimitivePropertiesInspectable {
+        private final boolean mBoolean;
+        private final byte mByte;
+        private final char mChar;
+        private final double mDouble;
+        private final float mFloat;
+        private final int mInt;
+        private final long mLong;
+        private final short mShort;
+
+        PrimitivePropertiesInspectable(Random seed) {
+            mBoolean = seed.nextBoolean();
+            mByte = (byte) seed.nextInt();
+            mChar = randomLetter(seed);
+            mDouble = seed.nextDouble();
+            mFloat = seed.nextFloat();
+            mInt = seed.nextInt();
+            mLong = seed.nextLong();
+            mShort = (short) seed.nextInt();
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public boolean getBoolean() {
+            return mBoolean;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public byte getByte() {
+            return mByte;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public char getChar() {
+            return mChar;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public double getDouble() {
+            return mDouble;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public float getFloat() {
+            return mFloat;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public int getInt() {
+            return mInt;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public long getLong() {
+            return mLong;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public short getShort() {
+            return mShort;
+        }
+    }
+
+    @Test
+    public void testPrimitiveProperties() {
+        PrimitivePropertiesInspectable inspectable = new PrimitivePropertiesInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getBoolean(), mPropertyReader.get("boolean"));
+        assertEquals(inspectable.getByte(), mPropertyReader.get("byte"));
+        assertEquals(inspectable.getChar(), mPropertyReader.get("char"));
+        assertEquals(inspectable.getDouble(), mPropertyReader.get("double"));
+        assertEquals(inspectable.getFloat(), mPropertyReader.get("float"));
+        assertEquals(inspectable.getInt(), mPropertyReader.get("int"));
+        assertEquals(inspectable.getLong(), mPropertyReader.get("long"));
+        assertEquals(inspectable.getShort(), mPropertyReader.get("short"));
+    }
+
+    class ObjectPropertiesInspectable {
+        private final String mText;
+
+        ObjectPropertiesInspectable(Random seed) {
+            final StringBuilder stringBuilder = new StringBuilder();
+            final int length = seed.nextInt(8) + 8;
+
+            for (int i = 0; i < length; i++) {
+                stringBuilder.append(randomLetter(seed));
+            }
+
+            mText = stringBuilder.toString();
+        }
+
+        @InspectableProperty
+        public String getText() {
+            return mText;
+        }
+
+        @InspectableProperty(hasAttributeId = false)
+        public Objects getNull() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testObjectProperties() {
+        ObjectPropertiesInspectable inspectable = new ObjectPropertiesInspectable(mRandom);
+        mapAndRead(inspectable);
+        assertEquals(inspectable.getText(), mPropertyReader.get("text"));
+        assertNull(mPropertyReader.get("null"));
+        assertNotEquals(0, mPropertyMapper.getId("null"));
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> void mapAndRead(T inspectable) {
+        InspectionCompanion<T> companion = loadCompanion((Class<T>) inspectable.getClass());
+        companion.mapProperties(mPropertyMapper);
+        companion.readProperties(inspectable, mPropertyReader);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> InspectionCompanion<T> loadCompanion(Class<T> cls) {
+        final ClassLoader classLoader = cls.getClassLoader();
+        final String companionName = String.format("%s$$InspectionCompanion", cls.getName());
+
+        try {
+            final Class<InspectionCompanion<T>> companion =
+                    (Class<InspectionCompanion<T>>) classLoader.loadClass(companionName);
+            return companion.newInstance();
+        } catch (ClassNotFoundException e) {
+            fail(String.format("Unable to load companion for %s", cls.getCanonicalName()));
+        } catch (InstantiationException | IllegalAccessException e) {
+            fail(String.format("Unable to instantiate companion for %s", cls.getCanonicalName()));
+        }
+
+        return null;
+    }
+
+    private char randomLetter(Random random) {
+        final String alphabet = "abcdefghijklmnopqrstuvwxyz";
+        return alphabet.charAt(random.nextInt(alphabet.length()));
+    }
+}
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java
new file mode 100644
index 0000000..6cdaaf1
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import android.view.inspector.InspectableProperty.ValueType;
+import android.view.inspector.IntEnumMapping;
+import android.view.inspector.IntFlagMapping;
+import android.view.inspector.PropertyMapper;
+
+import java.util.HashMap;
+
+class TestPropertyMapper implements PropertyMapper {
+    private final HashMap<String, Integer> mPropertyIds = new HashMap<>();
+    private final HashMap<String, Integer> mAttributeIds = new HashMap<>();
+    private final HashMap<String, ValueType> mValueTypes = new HashMap<>();
+    private int mNextId = 1;
+
+    int getId(String name) {
+        return mPropertyIds.getOrDefault(name, 0);
+    }
+
+    int getAttributeId(String name) {
+        return mAttributeIds.getOrDefault(name, 0);
+    }
+
+    ValueType getValueType(String name) {
+        return mValueTypes.getOrDefault(name, ValueType.NONE);
+    }
+
+    @Override
+    public int mapBoolean(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapByte(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapChar(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapDouble(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapFloat(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapInt(String name, int attributeId) { return map(name, attributeId); }
+
+    @Override
+    public int mapLong(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapShort(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapObject(String name, int attributeId) {
+        return map(name, attributeId);
+    }
+
+    @Override
+    public int mapColor(String name, int attributeId) {
+        return map(name, attributeId, ValueType.COLOR);
+    }
+
+    @Override
+    public int mapGravity(String name, int attributeId) {
+        return map(name, attributeId, ValueType.GRAVITY);
+    }
+
+    @Override
+    public int mapIntEnum(String name, int attributeId, IntEnumMapping intEnumMapping) {
+        return map(name, attributeId, ValueType.INT_ENUM);
+    }
+
+    @Override
+    public int mapIntFlag(String name, int attributeId, IntFlagMapping intFlagMapping) {
+        return map(name, attributeId, ValueType.INT_FLAG);
+    }
+
+    private int map(String name, int attributeId) {
+        return map(name, attributeId, ValueType.NONE);
+    }
+
+    private int map(String name, int attributeId, ValueType valueType) {
+        if (mPropertyIds.containsKey(name)) {
+            throw new PropertyConflictException(name, "all", "all");
+        }
+        mAttributeIds.put(name, attributeId);
+        mValueTypes.put(name, valueType);
+        return mPropertyIds.computeIfAbsent(name, n -> mNextId++);
+    }
+}
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java
new file mode 100644
index 0000000..100e733
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import android.graphics.Color;
+import android.util.SparseArray;
+import android.view.inspector.PropertyReader;
+
+import java.util.Objects;
+
+
+class TestPropertyReader implements PropertyReader {
+    private final TestPropertyMapper mPropertyMapper;
+    private final SparseArray<Object> mProperties = new SparseArray<>();
+
+    TestPropertyReader(TestPropertyMapper propertyMapper) {
+        mPropertyMapper = Objects.requireNonNull(propertyMapper);
+    }
+
+    Object get(int id) {
+        return mProperties.get(id);
+    }
+
+    Object get(String name) {
+        return mProperties.get(mPropertyMapper.getId(name));
+    }
+
+    @Override
+    public void readBoolean(int id, boolean value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readByte(int id, byte value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readChar(int id, char value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readDouble(int id, double value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readFloat(int id, float value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readInt(int id, int value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readLong(int id, long value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readShort(int id, short value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readObject(int id, Object value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readColor(int id, int value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readColor(int id, long value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readColor(int id, Color value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readGravity(int id, int value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readIntEnum(int id, int value) {
+        mProperties.put(id, value);
+    }
+
+    @Override
+    public void readIntFlag(int id, int value) {
+        mProperties.put(id, value);
+    }
+}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index e45d3db..898f329 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -78,6 +78,7 @@
         grantWriteSecureSettingsPermission(uiAutomation);
     }
 
+    @AppModeFull
     @Test
     public void testAdoptAllShellPermissions() {
         final Context context = getInstrumentation().getContext();
@@ -137,6 +138,7 @@
         }
     }
 
+    @AppModeFull
     @Test
     public void testAdoptSomeShellPermissions() {
         final Context context = getInstrumentation().getContext();
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
index c075105..d2cb027 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
@@ -16,19 +16,20 @@
 
 package android.uirendering.cts.bitmapverifiers;
 
+import android.graphics.Bitmap;
 import android.graphics.Color;
-import android.graphics.ColorSpace;
 import android.graphics.Point;
 import android.util.Half;
 import android.util.Log;
 
+import org.junit.Assert;
+
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 
-public class SamplePointWideGamutVerifier extends WideGamutBitmapVerifier {
+public class SamplePointWideGamutVerifier extends BitmapVerifier {
     private static final String TAG = "SamplePointWideGamut";
 
-    private static final ColorSpace SCRGB = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
-
     private final Point[] mPoints;
     private final Color[] mColors;
     private final float mEps;
@@ -40,31 +41,68 @@
     }
 
     @Override
-    public boolean verify(ByteBuffer bitmap, int offset, int stride, int width, int height) {
+    public boolean verify(Bitmap bitmap) {
+        Assert.assertTrue("You cannot use this verifier with an bitmap whose ColorSpace is not "
+                 + "wide gamut: " + bitmap.getColorSpace(), bitmap.getColorSpace().isWideGamut());
+
+        ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
+        bitmap.copyPixelsToBuffer(dst);
+        dst.rewind();
+        dst.order(ByteOrder.LITTLE_ENDIAN);
+
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        int stride = bitmap.getRowBytes();
+
         boolean success = true;
         for (int i = 0; i < mPoints.length; i++) {
             Point p = mPoints[i];
             Color c = mColors[i];
 
-            int index = p.y * stride + (p.x << 3);
-            float r = Half.toFloat(bitmap.getShort(index));
-            float g = Half.toFloat(bitmap.getShort(index + 2));
-            float b = Half.toFloat(bitmap.getShort(index + 4));
+            float r, g, b, a;
+
+            if (bitmap.getConfig() == Bitmap.Config.RGBA_F16) {
+                int index = p.y * stride + (p.x << 3);
+                r = Half.toFloat(dst.getShort(index));
+                g = Half.toFloat(dst.getShort(index + 2));
+                b = Half.toFloat(dst.getShort(index + 4));
+                a = Half.toFloat(dst.getShort(index + 6));
+            } else if (bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
+                int index = p.y * stride + (p.x << 2);
+                r = dst.get(index + 0) / 255.0f;
+                g = dst.get(index + 1) / 255.0f;
+                b = dst.get(index + 2) / 255.0f;
+                a = dst.get(index + 3) / 255.0f;
+            } else {
+                Assert.fail("This verifier does not support the provided bitmap config: "
+                        + bitmap.getConfig());
+                return false;
+            }
+
+            Color bitmapColor = Color.valueOf(r, g, b, a, bitmap.getColorSpace());
+            Color convertedBitmapColor = bitmapColor.convert(c.getColorSpace());
 
             boolean localSuccess = true;
-            if (!floatCompare(c.red(),   r, mEps)) localSuccess = false;
-            if (!floatCompare(c.green(), g, mEps)) localSuccess = false;
-            if (!floatCompare(c.blue(),  b, mEps)) localSuccess = false;
+            if (!floatCompare(c.red(),   convertedBitmapColor.red(),   mEps)) localSuccess = false;
+            if (!floatCompare(c.green(), convertedBitmapColor.green(), mEps)) localSuccess = false;
+            if (!floatCompare(c.blue(),  convertedBitmapColor.blue(),  mEps)) localSuccess = false;
+            if (!floatCompare(c.alpha(), convertedBitmapColor.alpha(), mEps)) localSuccess = false;
 
             if (!localSuccess) {
                 success = false;
                 Log.w(TAG, "Expected " + c.toString() + " at " + p.x + "x" + p.y
-                        + ", got " + Color.valueOf(r, g, b, 1.0f, SCRGB).toString());
+                        + ", got " + convertedBitmapColor.toString());
             }
         }
         return success;
     }
 
+    @Override
+    public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
+        Assert.fail("This verifier requires more info than can be encoded in sRGB (int) values");
+        return false;
+    }
+
     private static boolean floatCompare(float a, float b, float eps) {
         return Float.compare(a, b) == 0 || Math.abs(a - b) <= eps;
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java
deleted file mode 100644
index 0c11a064..0000000
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.uirendering.cts.bitmapverifiers;
-
-import android.graphics.Bitmap;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public abstract class WideGamutBitmapVerifier extends BitmapVerifier {
-    @Override
-    public boolean verify(Bitmap bitmap) {
-        ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
-        bitmap.copyPixelsToBuffer(dst);
-        dst.rewind();
-        dst.order(ByteOrder.LITTLE_ENDIAN);
-
-        int width = bitmap.getWidth();
-        int height = bitmap.getHeight();
-        return verify(dst, 0, bitmap.getRowBytes(), width, height);
-    }
-
-    public abstract boolean verify(ByteBuffer bitmap, int offset, int stride,
-            int width, int height);
-
-    @Override
-    public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
-        // This method is never called, we use
-        // verify(ByteBuffer bitmap, int offset, int stride, int width, int height) instead
-        return false;
-    }
-}
diff --git a/tests/tests/view/jni/Android.mk b/tests/tests/view/jni/Android.mk
index f1aad68..85c073b 100644
--- a/tests/tests/view/jni/Android.mk
+++ b/tests/tests/view/jni/Android.mk
@@ -24,12 +24,15 @@
 
 LOCAL_SRC_FILES := \
 		CtsViewJniOnLoad.cpp \
+		android_view_cts_ASurfaceControlTest.cpp \
 		android_view_cts_ChoreographerNativeTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog libsync
 
-LOCAL_CXX_STL := libc++_static
+LOCAL_NDK_STL_VARIANT := c++_static
+
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/view/jni/CtsViewJniOnLoad.cpp b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
index 1a7ef3c..a6f50ca 100644
--- a/tests/tests/view/jni/CtsViewJniOnLoad.cpp
+++ b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
@@ -17,8 +17,8 @@
 #include <jni.h>
 
 #define LOG_TAG "CtsViewJniOnLoad"
-#include <utils/Log.h>
 
+extern int register_android_view_cts_ASurfaceControlTest(JNIEnv *);
 extern int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env);
 
 jint JNI_OnLoad(JavaVM *vm, void *) {
@@ -26,6 +26,9 @@
     if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
         return JNI_ERR;
     }
+    if (register_android_view_cts_ASurfaceControlTest(env)) {
+      return JNI_ERR;
+    }
     if (register_android_view_cts_ChoreographerNativeTest(env)) {
         return JNI_ERR;
     }
diff --git a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
new file mode 100644
index 0000000..dd6a186
--- /dev/null
+++ b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ASurfaceControlTest"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <array>
+#include <cinttypes>
+#include <string>
+
+#include <android/hardware_buffer.h>
+#include <android/log.h>
+#include <android/native_window_jni.h>
+#include <android/surface_control.h>
+#include <android/sync.h>
+
+#include <jni.h>
+
+namespace {
+
+// Raises a java exception
+static void fail(JNIEnv* env, const char* format, ...) {
+    va_list args;
+
+    va_start(args, format);
+    char* msg;
+    vasprintf(&msg, format, args);
+    va_end(args);
+
+    jclass exClass;
+    const char* className = "java/lang/AssertionError";
+    exClass = env->FindClass(className);
+    env->ThrowNew(exClass, msg);
+    free(msg);
+}
+
+#define ASSERT(condition, format, args...) \
+    if (!(condition)) {                    \
+        fail(env, format, ##args);         \
+        return;                            \
+    }
+
+static AHardwareBuffer* allocateBuffer(int32_t width, int32_t height) {
+    AHardwareBuffer* buffer = nullptr;
+    AHardwareBuffer_Desc desc = {};
+    desc.width = width;
+    desc.height = height;
+    desc.layers = 1;
+    desc.usage = AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+    desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+
+    AHardwareBuffer_allocate(&desc, &buffer);
+
+    return buffer;
+}
+
+static void fillRegion(void* data, int32_t left, int32_t top, int32_t right,
+                       int32_t bottom, uint32_t color, uint32_t stride) {
+    uint32_t* ptr = static_cast<uint32_t*>(data);
+
+    ptr += stride * top;
+
+    for (uint32_t y = top; y < bottom; y++) {
+        for (uint32_t x = left; x < right; x++) {
+            ptr[x] = color;
+        }
+        ptr += stride;
+    }
+}
+
+static bool getSolidBuffer(int32_t width, int32_t height, uint32_t color,
+                           AHardwareBuffer** outHardwareBuffer,
+                           int* outFence) {
+    AHardwareBuffer* buffer = allocateBuffer(width, height);
+    if (!buffer) {
+        return true;
+    }
+
+    AHardwareBuffer_Desc desc = {};
+    AHardwareBuffer_describe(buffer, &desc);
+
+    void* data = nullptr;
+    const ARect rect{0, 0, width, height};
+    AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
+                                             &data);
+    if (!data) {
+        return true;
+    }
+
+    fillRegion(data, 0, 0, width, height, color, desc.stride);
+
+    AHardwareBuffer_unlock(buffer, outFence);
+
+    *outHardwareBuffer = buffer;
+    return false;
+}
+
+static bool getQuadrantBuffer(int32_t width, int32_t height, jint colorTopLeft,
+                              jint colorTopRight, jint colorBottomRight,
+                              jint colorBottomLeft,
+                              AHardwareBuffer** outHardwareBuffer,
+                              int* outFence) {
+    AHardwareBuffer* buffer = allocateBuffer(width, height);
+    if (!buffer) {
+        return true;
+    }
+
+    AHardwareBuffer_Desc desc = {};
+    AHardwareBuffer_describe(buffer, &desc);
+
+    void* data = nullptr;
+    const ARect rect{0, 0, width, height};
+    AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
+                                             &data);
+    if (!data) {
+        return true;
+    }
+
+    fillRegion(data, 0, 0, width / 2, height / 2, colorTopLeft, desc.stride);
+    fillRegion(data, width / 2, 0, width, height / 2, colorTopRight, desc.stride);
+    fillRegion(data, 0, height / 2, width / 2, height, colorBottomLeft,
+                         desc.stride);
+    fillRegion(data, width / 2, height / 2, width, height, colorBottomRight,
+                         desc.stride);
+
+    AHardwareBuffer_unlock(buffer, outFence);
+
+    *outHardwareBuffer = buffer;
+    return false;
+}
+
+jlong SurfaceTransaction_create(JNIEnv* /*env*/, jclass) {
+    return reinterpret_cast<jlong>(ASurfaceTransaction_create());
+}
+
+void SurfaceTransaction_delete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+    ASurfaceTransaction_delete(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
+}
+
+void SurfaceTransaction_apply(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+    ASurfaceTransaction_apply(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
+}
+
+long SurfaceControl_createFromWindow(JNIEnv* env, jclass, jobject jSurface) {
+    if (!jSurface) {
+        return 0;
+    }
+
+    ANativeWindow* window = ANativeWindow_fromSurface(env, jSurface);
+    if (!window) {
+        return 0;
+    }
+
+    const std::string debugName = "SurfaceControl_createFromWindowLayer";
+    ASurfaceControl* surfaceControl =
+            ASurfaceControl_createFromWindow(window, debugName.c_str());
+    if (!surfaceControl) {
+        return 0;
+    }
+
+    ANativeWindow_release(window);
+
+    return reinterpret_cast<jlong>(surfaceControl);
+}
+
+jlong SurfaceControl_create(JNIEnv* /*env*/, jclass, jlong parentSurfaceControlId) {
+    ASurfaceControl* surfaceControl = nullptr;
+    const std::string debugName = "SurfaceControl_create";
+
+    surfaceControl = ASurfaceControl_create(
+            reinterpret_cast<ASurfaceControl*>(parentSurfaceControlId),
+            debugName.c_str());
+
+    return reinterpret_cast<jlong>(surfaceControl);
+}
+
+void SurfaceControl_release(JNIEnv* /*env*/, jclass, jlong surfaceControl) {
+    ASurfaceControl_release(reinterpret_cast<ASurfaceControl*>(surfaceControl));
+}
+
+jlong SurfaceTransaction_setSolidBuffer(JNIEnv* /*env*/, jclass,
+                                        jlong surfaceControl,
+                                        jlong surfaceTransaction, jint width,
+                                        jint height, jint color) {
+    AHardwareBuffer* buffer = nullptr;
+    int fence = -1;
+
+    bool err = getSolidBuffer(width, height, color, &buffer, &fence);
+    if (err) {
+        return 0;
+    }
+
+    ASurfaceTransaction_setBuffer(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+
+    return reinterpret_cast<jlong>(buffer);
+}
+
+jlong SurfaceTransaction_setQuadrantBuffer(
+        JNIEnv* /*env*/, jclass, jlong surfaceControl, jlong surfaceTransaction,
+        jint width, jint height, jint colorTopLeft, jint colorTopRight,
+        jint colorBottomRight, jint colorBottomLeft) {
+    AHardwareBuffer* buffer = nullptr;
+    int fence = -1;
+
+    bool err =
+            getQuadrantBuffer(width, height, colorTopLeft, colorTopRight,
+                              colorBottomRight, colorBottomLeft, &buffer, &fence);
+    if (err) {
+        return 0;
+    }
+
+    ASurfaceTransaction_setBuffer(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+
+    return reinterpret_cast<jlong>(buffer);
+}
+
+void SurfaceTransaction_releaseBuffer(JNIEnv* /*env*/, jclass, jlong buffer) {
+    AHardwareBuffer_release(reinterpret_cast<AHardwareBuffer*>(buffer));
+}
+
+void SurfaceTransaction_setVisibility(JNIEnv* /*env*/, jclass,
+                                      jlong surfaceControl,
+                                      jlong surfaceTransaction, jboolean show) {
+    int8_t visibility = (show) ? ASURFACE_TRANSACTION_VISIBILITY_SHOW :
+                                 ASURFACE_TRANSACTION_VISIBILITY_HIDE;
+    ASurfaceTransaction_setVisibility(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), visibility);
+}
+
+void SurfaceTransaction_setBufferOpaque(JNIEnv* /*env*/, jclass,
+                                        jlong surfaceControl,
+                                        jlong surfaceTransaction,
+                                        jboolean opaque) {
+    int8_t transparency = (opaque) ? ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE :
+                                   ASURFACE_TRANSACTION_TRANSPARENCY_TRANSPARENT;
+    ASurfaceTransaction_setBufferTransparency(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), transparency);
+}
+
+void SurfaceTransaction_setGeometry(JNIEnv* /*env*/, jclass,
+                                    jlong surfaceControl,
+                                    jlong surfaceTransaction,
+                                    jint srcLeft, jint srcTop, jint srcRight, jint srcBottom,
+                                    jint dstLeft, jint dstTop, jint dstRight, jint dstBottom,
+                                    jint transform) {
+    const ARect src{srcLeft, srcTop, srcRight, srcBottom};
+    const ARect dst{dstLeft, dstTop, dstRight, dstBottom};
+    ASurfaceTransaction_setGeometry(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), src, dst, transform);
+}
+
+void SurfaceTransaction_setDamageRegion(JNIEnv* /*env*/, jclass,
+                                        jlong surfaceControl,
+                                        jlong surfaceTransaction, jint left,
+                                        jint top, jint right, jint bottom) {
+    const ARect rect[] = {{left, top, right, bottom}};
+    ASurfaceTransaction_setDamageRegion(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), rect, 1);
+}
+
+void SurfaceTransaction_setZOrder(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+                                  jlong surfaceTransaction, jint z) {
+    ASurfaceTransaction_setZOrder(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), z);
+}
+
+static void onComplete(void* context, ASurfaceTransactionStats* stats) {
+    if (!stats) {
+        return;
+    }
+
+    int64_t latchTime = ASurfaceTransactionStats_getLatchTime(stats);
+    if (latchTime < 0) {
+        return;
+    }
+
+    ASurfaceControl** surfaceControls = nullptr;
+    size_t surfaceControlsSize = 0;
+    ASurfaceTransactionStats_getASurfaceControls(stats, &surfaceControls, &surfaceControlsSize);
+
+    for (int i = 0; i < surfaceControlsSize; i++) {
+        ASurfaceControl* surfaceControl = surfaceControls[i];
+
+        int64_t acquireTime = ASurfaceTransactionStats_getAcquireTime(stats, surfaceControl);
+        if (acquireTime < -1) {
+            return;
+        }
+
+        int previousReleaseFence = ASurfaceTransactionStats_getPreviousReleaseFenceFd(
+                    stats, surfaceControl);
+        close(previousReleaseFence);
+    }
+
+    int presentFence = ASurfaceTransactionStats_getPresentFenceFd(stats);
+
+    if (!context) {
+        close(presentFence);
+        return;
+    }
+
+    int* contextIntPtr = reinterpret_cast<int*>(context);
+    contextIntPtr[0]++;
+    contextIntPtr[1] = presentFence;
+}
+
+jlong SurfaceTransaction_setOnComplete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+    int* context = new int[2];
+    context[0] = 0;
+    context[1] = -1;
+
+    ASurfaceTransaction_setOnComplete(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<void*>(context), onComplete);
+    return reinterpret_cast<jlong>(context);
+}
+
+void SurfaceTransaction_checkOnComplete(JNIEnv* env, jclass, jlong context,
+                                        jlong desiredPresentTime) {
+    ASSERT(context != 0, "invalid context")
+
+    int* contextPtr = reinterpret_cast<int*>(context);
+    int data = contextPtr[0];
+    int presentFence = contextPtr[1];
+
+    delete[] contextPtr;
+
+    if (desiredPresentTime < 0) {
+        close(presentFence);
+        ASSERT(data >= 1, "did not receive a callback")
+        ASSERT(data <= 1, "received too many callbacks")
+        return;
+    }
+
+    struct sync_file_info* syncFileInfo = sync_file_info(presentFence);
+    ASSERT(syncFileInfo, "invalid fence")
+
+    if (syncFileInfo->status != 1) {
+        sync_file_info_free(syncFileInfo);
+        ASSERT(syncFileInfo->status == 1, "fence did not signal")
+    }
+
+    uint64_t presentTime = 0;
+    struct sync_fence_info* syncFenceInfo = sync_get_fence_info(syncFileInfo);
+    for (size_t i = 0; i < syncFileInfo->num_fences; i++) {
+        if (syncFenceInfo[i].timestamp_ns > presentTime) {
+            presentTime = syncFenceInfo[i].timestamp_ns;
+        }
+    }
+
+    sync_file_info_free(syncFileInfo);
+    close(presentFence);
+
+    // In the worst case the worst present time should be no more than three frames off from the
+    // desired present time. Since the test case is using a virtual display and there are no
+    // requirements for virtual display refresh rate timing, lets assume a refresh rate of 16fps.
+    ASSERT(presentTime < desiredPresentTime + 0.188 * 1e9, "transaction was presented too late");
+    ASSERT(presentTime >= desiredPresentTime, "transaction was presented too early");
+
+    ASSERT(data >= 1, "did not receive a callback")
+    ASSERT(data <= 1, "received too many callbacks")
+}
+
+jlong SurfaceTransaction_setDesiredPresentTime(JNIEnv* /*env*/, jclass, jlong surfaceTransaction,
+                                              jlong desiredPresentTimeOffset) {
+    struct timespec t;
+    t.tv_sec = t.tv_nsec = 0;
+    clock_gettime(CLOCK_MONOTONIC, &t);
+    int64_t currentTime = ((int64_t) t.tv_sec)*1000000000LL + t.tv_nsec;
+
+    int64_t desiredPresentTime = currentTime + desiredPresentTimeOffset;
+
+    ASurfaceTransaction_setDesiredPresentTime(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction), desiredPresentTime);
+
+    return desiredPresentTime;
+}
+
+void SurfaceTransaction_setBufferAlpha(JNIEnv* /*env*/, jclass,
+                                      jlong surfaceControl,
+                                      jlong surfaceTransaction, jdouble alpha) {
+    ASurfaceTransaction_setBufferAlpha(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl), alpha);
+}
+
+void SurfaceTransaction_reparent(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+                                 jlong newParentSurfaceControl, jlong surfaceTransaction) {
+    ASurfaceTransaction_reparent(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl),
+            reinterpret_cast<ASurfaceControl*>(newParentSurfaceControl));
+}
+
+void SurfaceTransaction_setColor(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+                                 jlong surfaceTransaction, jfloat r,
+                                 jfloat g, jfloat b, jfloat alpha) {
+    ASurfaceTransaction_setColor(
+            reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+            reinterpret_cast<ASurfaceControl*>(surfaceControl),
+            r, g, b, alpha, ADATASPACE_UNKNOWN);
+}
+
+const std::array<JNINativeMethod, 20> JNI_METHODS = {{
+    {"nSurfaceTransaction_create", "()J", (void*)SurfaceTransaction_create},
+    {"nSurfaceTransaction_delete", "(J)V", (void*)SurfaceTransaction_delete},
+    {"nSurfaceTransaction_apply", "(J)V", (void*)SurfaceTransaction_apply},
+    {"nSurfaceControl_createFromWindow", "(Landroid/view/Surface;)J",
+                                            (void*)SurfaceControl_createFromWindow},
+    {"nSurfaceControl_create", "(J)J", (void*)SurfaceControl_create},
+    {"nSurfaceControl_release", "(J)V", (void*)SurfaceControl_release},
+    {"nSurfaceTransaction_setSolidBuffer", "(JJIII)J", (void*)SurfaceTransaction_setSolidBuffer},
+    {"nSurfaceTransaction_setQuadrantBuffer", "(JJIIIIII)J",
+                                            (void*)SurfaceTransaction_setQuadrantBuffer},
+    {"nSurfaceTransaction_releaseBuffer", "(J)V", (void*)SurfaceTransaction_releaseBuffer},
+    {"nSurfaceTransaction_setVisibility", "(JJZ)V", (void*)SurfaceTransaction_setVisibility},
+    {"nSurfaceTransaction_setBufferOpaque", "(JJZ)V", (void*)SurfaceTransaction_setBufferOpaque},
+    {"nSurfaceTransaction_setGeometry", "(JJIIIIIIIII)V", (void*)SurfaceTransaction_setGeometry},
+    {"nSurfaceTransaction_setDamageRegion", "(JJIIII)V", (void*)SurfaceTransaction_setDamageRegion},
+    {"nSurfaceTransaction_setZOrder", "(JJI)V", (void*)SurfaceTransaction_setZOrder},
+    {"nSurfaceTransaction_setOnComplete", "(J)J", (void*)SurfaceTransaction_setOnComplete},
+    {"nSurfaceTransaction_checkOnComplete", "(JJ)V", (void*)SurfaceTransaction_checkOnComplete},
+    {"nSurfaceTransaction_setDesiredPresentTime", "(JJ)J",
+                                            (void*)SurfaceTransaction_setDesiredPresentTime},
+    {"nSurfaceTransaction_setBufferAlpha", "(JJD)V", (void*)SurfaceTransaction_setBufferAlpha},
+    {"nSurfaceTransaction_reparent", "(JJJ)V", (void*)SurfaceTransaction_reparent},
+    {"nSurfaceTransaction_setColor", "(JJFFFF)V", (void*)SurfaceTransaction_setColor},
+}};
+
+}  // anonymous namespace
+
+jint register_android_view_cts_ASurfaceControlTest(JNIEnv* env) {
+    jclass clazz = env->FindClass("android/view/cts/ASurfaceControlTest");
+    return env->RegisterNatives(clazz, JNI_METHODS.data(), JNI_METHODS.size());
+}
diff --git a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
new file mode 100644
index 0000000..eb9f513
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
@@ -0,0 +1,1356 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import static org.junit.Assert.assertTrue;
+
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+import android.view.cts.surfacevalidator.AnimationFactory;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class ASurfaceControlTest {
+    static {
+        System.loadLibrary("ctsview_jni");
+    }
+
+    private static final String TAG = ASurfaceControlTest.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private static final int DEFAULT_LAYOUT_WIDTH = 100;
+    private static final int DEFAULT_LAYOUT_HEIGHT = 100;
+    private static final int DEFAULT_BUFFER_WIDTH = 640;
+    private static final int DEFAULT_BUFFER_HEIGHT = 480;
+
+    @Rule
+    public ActivityTestRule<CapturedActivity> mActivityRule =
+            new ActivityTestRule<>(CapturedActivity.class);
+
+    @Rule
+    public TestName mName = new TestName();
+
+    private CapturedActivity mActivity;
+
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    /**
+     * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+     * after test.
+     */
+    @After
+    public void tearDown() throws UiObjectNotFoundException {
+        mActivity.dismissPermissionDialog();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // SurfaceHolder.Callbacks
+    ///////////////////////////////////////////////////////////////////////////
+
+    private abstract class BasicSurfaceHolderCallback implements SurfaceHolder.Callback {
+        private Set<Long> mSurfaceControls = new HashSet<Long>();
+        private Set<Long> mBuffers = new HashSet<Long>();
+
+        @Override
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
+
+        @Override
+        public void surfaceDestroyed(SurfaceHolder holder) {
+            for (Long surfaceControl : mSurfaceControls) {
+                reparent(surfaceControl, 0);
+                nSurfaceControl_release(surfaceControl);
+            }
+            mSurfaceControls.clear();
+
+            for (Long buffer : mBuffers) {
+                nSurfaceTransaction_releaseBuffer(buffer);
+            }
+            mBuffers.clear();
+        }
+
+        public long createSurfaceTransaction() {
+            long surfaceTransaction = nSurfaceTransaction_create();
+            assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+            return surfaceTransaction;
+        }
+
+        public void applySurfaceTransaction(long surfaceTransaction) {
+            nSurfaceTransaction_apply(surfaceTransaction);
+        }
+
+        public void deleteSurfaceTransaction(long surfaceTransaction) {
+            nSurfaceTransaction_delete(surfaceTransaction);
+        }
+
+        public void applyAndDeleteSurfaceTransaction(long surfaceTransaction) {
+            nSurfaceTransaction_apply(surfaceTransaction);
+            nSurfaceTransaction_delete(surfaceTransaction);
+        }
+
+        public long createFromWindow(Surface surface) {
+            long surfaceControl = nSurfaceControl_createFromWindow(surface);
+            assertTrue("failed to create surface control", surfaceControl != 0);
+
+            mSurfaceControls.add(surfaceControl);
+            return surfaceControl;
+        }
+
+        public long create(long parentSurfaceControl) {
+            long childSurfaceControl = nSurfaceControl_create(parentSurfaceControl);
+            assertTrue("failed to create child surface control", childSurfaceControl != 0);
+
+            mSurfaceControls.add(childSurfaceControl);
+            return childSurfaceControl;
+        }
+
+        public void setSolidBuffer(
+                long surfaceControl, long surfaceTransaction, int width, int height, int color) {
+            long buffer = nSurfaceTransaction_setSolidBuffer(
+                    surfaceControl, surfaceTransaction, width, height, color);
+            assertTrue("failed to set buffer", buffer != 0);
+            mBuffers.add(buffer);
+        }
+
+        public void setSolidBuffer(long surfaceControl, int width, int height, int color) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setSolidBuffer(surfaceControl, surfaceTransaction, width, height, color);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width,
+                int height, int colorTopLeft, int colorTopRight, int colorBottomRight,
+                int colorBottomLeft) {
+            long buffer = nSurfaceTransaction_setQuadrantBuffer(surfaceControl, surfaceTransaction,
+                    width, height, colorTopLeft, colorTopRight, colorBottomRight, colorBottomLeft);
+            assertTrue("failed to set buffer", buffer != 0);
+            mBuffers.add(buffer);
+        }
+
+        public void setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft,
+                int colorTopRight, int colorBottomRight, int colorBottomLeft) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setQuadrantBuffer(surfaceControl, surfaceTransaction, width, height, colorTopLeft,
+                    colorTopRight, colorBottomRight, colorBottomLeft);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setVisibility(long surfaceControl, long surfaceTransaction, boolean visible) {
+            nSurfaceTransaction_setVisibility(surfaceControl, surfaceTransaction, visible);
+        }
+
+        public void setVisibility(long surfaceControl, boolean visible) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setVisibility(surfaceControl, surfaceTransaction, visible);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setBufferOpaque(long surfaceControl, long surfaceTransaction, boolean opaque) {
+            nSurfaceTransaction_setBufferOpaque(surfaceControl, surfaceTransaction, opaque);
+        }
+
+        public void setBufferOpaque(long surfaceControl, boolean opaque) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setBufferOpaque(surfaceControl, surfaceTransaction, opaque);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setGeometry(long surfaceControl, long surfaceTransaction, int srcLeft,
+                int srcTop, int srcRight, int srcBottom, int dstLeft, int dstTop, int dstRight,
+                int dstBottom, int transform) {
+            nSurfaceTransaction_setGeometry(
+                    surfaceControl, surfaceTransaction, srcLeft, srcTop, srcRight, srcBottom,
+                    dstLeft, dstTop, dstRight, dstBottom, transform);
+        }
+
+        public void setGeometry(long surfaceControl, int srcLeft, int srcTop, int srcRight,
+                int srcBottom, int dstLeft, int dstTop, int dstRight, int dstBottom,
+                int transform) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setGeometry(surfaceControl, surfaceTransaction, srcLeft, srcTop, srcRight, srcBottom,
+                    dstLeft, dstTop, dstRight, dstBottom, transform);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setDamageRegion(long surfaceControl, long surfaceTransaction, int left, int top,
+                int right, int bottom) {
+            nSurfaceTransaction_setDamageRegion(
+                    surfaceControl, surfaceTransaction, left, top, right, bottom);
+        }
+
+        public void setDamageRegion(long surfaceControl, int left, int top, int right, int bottom) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setDamageRegion(surfaceControl, surfaceTransaction, left, top, right, bottom);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setZOrder(long surfaceControl, long surfaceTransaction, int z) {
+            nSurfaceTransaction_setZOrder(surfaceControl, surfaceTransaction, z);
+        }
+
+        public void setZOrder(long surfaceControl, int z) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setZOrder(surfaceControl, surfaceTransaction, z);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void setBufferAlpha(long surfaceControl, long surfaceTransaction, double alpha) {
+            nSurfaceTransaction_setBufferAlpha(surfaceControl, surfaceTransaction, alpha);
+        }
+
+        public void setBufferAlpha(long surfaceControl, double alpha) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setBufferAlpha(surfaceControl, surfaceTransaction, alpha);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+
+        public void reparent(long surfaceControl, long newParentSurfaceControl,
+                             long surfaceTransaction) {
+            nSurfaceTransaction_reparent(surfaceControl, newParentSurfaceControl,
+                                         surfaceTransaction);
+        }
+
+        public void reparent(long surfaceControl, long newParentSurfaceControl) {
+            long surfaceTransaction = createSurfaceTransaction();
+            reparent(surfaceControl, newParentSurfaceControl, surfaceTransaction);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // AnimationFactories
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static ValueAnimator makeInfinite(ValueAnimator a) {
+        a.setRepeatMode(ObjectAnimator.REVERSE);
+        a.setRepeatCount(ObjectAnimator.INFINITE);
+        a.setDuration(200);
+        a.setInterpolator(new LinearInterpolator());
+        return a;
+    }
+
+    private static AnimationFactory sTranslateAnimationFactory = view -> {
+        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 10f, 30f);
+        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 10f, 30f);
+        return makeInfinite(ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY));
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Tests
+    ///////////////////////////////////////////////////////////////////////////
+
+    private void verifyTest(SurfaceHolder.Callback callback, PixelChecker pixelChecker)
+                throws Throwable {
+        mActivity.verifyTest(new SurfaceControlTestCase(callback, sTranslateAnimationFactory,
+                                                 pixelChecker,
+                                                 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                                 DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT),
+                mName);
+    }
+
+    @Test
+    public void testSurfaceTransaction_create() {
+        mActivity.dismissPermissionDialog();
+
+        long surfaceTransaction = nSurfaceTransaction_create();
+        assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+
+        nSurfaceTransaction_delete(surfaceTransaction);
+    }
+
+    @Test
+    public void testSurfaceTransaction_apply() {
+        mActivity.dismissPermissionDialog();
+
+        long surfaceTransaction = nSurfaceTransaction_create();
+        assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+
+        Log.e("Transaction", "created: " + surfaceTransaction);
+
+        nSurfaceTransaction_apply(surfaceTransaction);
+        nSurfaceTransaction_delete(surfaceTransaction);
+    }
+
+    // INTRO: The following tests run a series of commands and verify the
+    // output based on the number of pixels with a certain color on the display.
+    //
+    // The interface being tested is a NDK api but the only way to record the display
+    // through public apis is in through the SDK. So the test logic and test verification
+    // is in Java but the hooks that call into the NDK api are jni code.
+    //
+    // The set up is done during the surfaceCreated callback. In most cases, the
+    // test uses the opportunity to create a child layer through createFromWindow and
+    // performs operations on the child layer.
+    //
+    // When there is no visible buffer for the layer(s) the color defaults to black.
+    // The test cases allow a +/- 10% error rate. This is based on the error
+    // rate allowed in the SurfaceViewSyncTests
+
+    @Test
+    public void testSurfaceControl_createFromWindow() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceControl_create() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBuffer() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBuffer_parentAndChild() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+
+                        setSolidBuffer(parentSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.BLUE);
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBuffer_childOnly() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setVisibility_show() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setVisibility(surfaceControl, true);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setVisibility_hide() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setVisibility(surfaceControl, false);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferOpaque_opaque() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setBufferOpaque(surfaceControl, true);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferOpaque_transparent() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.TRANSPARENT_RED);
+                        setBufferOpaque(surfaceControl, false);
+                    }
+                },
+                // setBufferOpaque is an optimization that can be used by SurfaceFlinger.
+                // It isn't required to affect SurfaceFlinger's behavior.
+                //
+                // Ideally we would check for a specific blending of red with a layer below
+                // it. Unfortunately we don't know what blending the layer will use and
+                // we don't know what variation the GPU/DPU/blitter might have. Although
+                // we don't know what shade of red might be present, we can at least check
+                // that the optimization doesn't cause the framework to drop the buffer entirely.
+                new PixelChecker(PixelColor.BLACK) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 640, 480, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_small() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, 64, 48, 320, 240, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //1600
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 1440 && pixelCount < 1760;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_childSmall() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        setGeometry(childSurfaceControl, 0, 0, 100, 100, 64, 48, 320, 240, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //1600
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 1440 && pixelCount < 1760;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_extraLarge() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, -100, -100, 740, 580, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_childExtraLarge() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        setGeometry(childSurfaceControl, 0, 0, 100, 100, -100, -100, 740, 580, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_negativeOffset() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, -32, -24, 320, 240, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_outOfParentBounds() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, 320, 240, 704, 504, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDestinationRect_twoLayers() throws Throwable {
+        BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLUE);
+                        setGeometry(surfaceControl1, 0, 0, 100, 100, 64, 48, 192, 192, 0);
+                        setGeometry(surfaceControl2, 0, 0, 100, 100, 448, 96, 576, 240, 0);
+                    }
+                };
+        verifyTest(callback,
+                new PixelChecker(PixelColor.RED) { //600
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 540 && pixelCount < 660;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLUE) { //600
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 540 && pixelCount < 660;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setSourceRect() throws Throwable {
+        BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 640, 480, 0);
+                    }
+                };
+        verifyTest(callback,
+                new PixelChecker(PixelColor.RED) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLUE) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLACK) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.GREEN) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setSourceRect_smallCentered() throws Throwable {
+        BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, 10, 10, 90, 90, 0, 0, 640, 480, 0);
+                    }
+                };
+        verifyTest(callback,
+                new PixelChecker(PixelColor.RED) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLUE) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLACK) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.GREEN) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setSourceRect_small() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //5000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 4500 && pixelCount < 5500;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setSourceRect_extraLarge() throws Throwable {
+        BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, -50, -50, 150, 150, 0, 0, 640, 480, 0);
+                    }
+                };
+        verifyTest(callback,
+                new PixelChecker(PixelColor.RED) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLUE) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLACK) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.GREEN) { //2500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 2250 && pixelCount < 2750;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setSourceRect_badOffset() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, -50, -50, 50, 50, 0, 0, 640, 480, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setTransform_flipH() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
+                                    /*NATIVE_WINDOW_TRANSFORM_FLIP_H*/ 1);
+                    }
+                },
+                new PixelChecker(PixelColor.BLUE) { //5000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 4500 && pixelCount < 5500;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setTransform_rotate180() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+                                PixelColor.BLACK, PixelColor.GREEN);
+                        setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
+                                    /*NATIVE_WINDOW_TRANSFORM_ROT_180*/ 3);
+                    }
+                },
+                new PixelChecker(PixelColor.BLUE) { //5000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 4500 && pixelCount < 5500;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDamageRegion_all() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+
+                        long surfaceTransaction = createSurfaceTransaction();
+                        setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.BLUE);
+                        setDamageRegion(surfaceControl, surfaceTransaction, 0, 0, 100, 100);
+                        applyAndDeleteSurfaceTransaction(surfaceTransaction);
+                    }
+                },
+                new PixelChecker(PixelColor.BLUE) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setZOrder_zero() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLACK);
+
+                        setZOrder(surfaceControl1, 1);
+                        setZOrder(surfaceControl2, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setZOrder_positive() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLACK);
+
+                        setZOrder(surfaceControl1, 1);
+                        setZOrder(surfaceControl2, 5);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setZOrder_negative() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLACK);
+
+                        setZOrder(surfaceControl1, 1);
+                        setZOrder(surfaceControl2, -15);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setZOrder_max() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLACK);
+
+                        setZOrder(surfaceControl1, 1);
+                        setZOrder(surfaceControl2, Integer.MAX_VALUE);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setZOrder_min() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl1 = createFromWindow(holder.getSurface());
+                        long surfaceControl2 = createFromWindow(holder.getSurface());
+                        setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.BLACK);
+
+                        setZOrder(surfaceControl1, 1);
+                        setZOrder(surfaceControl2, Integer.MIN_VALUE);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setOnComplete() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    private long mContext;
+
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        long surfaceTransaction = createSurfaceTransaction();
+                        setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+                        applyAndDeleteSurfaceTransaction(surfaceTransaction);
+                    }
+                    @Override
+                    public void surfaceDestroyed(SurfaceHolder holder) {
+                        super.surfaceDestroyed(holder);
+                        nSurfaceTransaction_checkOnComplete(mContext, -1);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDesiredPresentTime_now() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    private long mContext;
+                    private long mDesiredPresentTime;
+
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        long surfaceTransaction = createSurfaceTransaction();
+                        setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+                                surfaceTransaction, 0);
+                        mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+                        applyAndDeleteSurfaceTransaction(surfaceTransaction);
+                    }
+                    @Override
+                    public void surfaceDestroyed(SurfaceHolder holder) {
+                        super.surfaceDestroyed(holder);
+                        nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDesiredPresentTime_30ms() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    private long mContext;
+                    private long mDesiredPresentTime;
+
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        long surfaceTransaction = createSurfaceTransaction();
+                        setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+                                surfaceTransaction, 30000000);
+                        mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+                        applyAndDeleteSurfaceTransaction(surfaceTransaction);
+                    }
+                    @Override
+                    public void surfaceDestroyed(SurfaceHolder holder) {
+                        super.surfaceDestroyed(holder);
+                        nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setDesiredPresentTime_100ms() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    private long mContext;
+                    private long mDesiredPresentTime;
+
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        long surfaceTransaction = createSurfaceTransaction();
+                        setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                        mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+                                surfaceTransaction, 100000000);
+                        mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+                        applyAndDeleteSurfaceTransaction(surfaceTransaction);
+                    }
+                    @Override
+                    public void surfaceDestroyed(SurfaceHolder holder) {
+                        super.surfaceDestroyed(holder);
+                        nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferAlpha_1_0() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setBufferAlpha(surfaceControl, 1.0);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferAlpha_0_5() throws Throwable {
+        BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setBufferAlpha(surfaceControl, 0.5);
+                    }
+                };
+        verifyTest(callback,
+                new PixelChecker(PixelColor.BLACK) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+        verifyTest(callback,
+                new PixelChecker(PixelColor.RED) {
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount == 0;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferAlpha_0_0() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long surfaceControl = createFromWindow(holder.getSurface());
+
+                        setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                                PixelColor.RED);
+                        setBufferAlpha(surfaceControl, 0.0);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_reparent() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl1 = createFromWindow(holder.getSurface());
+                        long parentSurfaceControl2 = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl1);
+
+                        setGeometry(parentSurfaceControl1, 0, 0, 100, 100, 0, 0, 160, 480, 0);
+                        setGeometry(parentSurfaceControl2, 0, 0, 100, 100, 160, 0, 640, 480, 0);
+
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+
+                        reparent(childSurfaceControl, parentSurfaceControl2);
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //7500
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 6750 && pixelCount < 8250;
+                    }
+                });
+    }
+
+    @Test
+    public void testSurfaceTransaction_reparent_null() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                    @Override
+                    public void surfaceCreated(SurfaceHolder holder) {
+                        long parentSurfaceControl = createFromWindow(holder.getSurface());
+                        long childSurfaceControl = create(parentSurfaceControl);
+
+                        setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                                DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+
+                        reparent(childSurfaceControl, 0);
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Native function prototypes
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static native long nSurfaceTransaction_create();
+    private static native void nSurfaceTransaction_delete(long surfaceTransaction);
+    private static native void nSurfaceTransaction_apply(long surfaceTransaction);
+    private static native long nSurfaceControl_createFromWindow(Surface surface);
+    private static native long nSurfaceControl_create(long surfaceControl);
+    private static native void nSurfaceControl_release(long surfaceControl);
+    private static native long nSurfaceTransaction_setSolidBuffer(
+            long surfaceControl, long surfaceTransaction, int width, int height, int color);
+    private static native long nSurfaceTransaction_setQuadrantBuffer(long surfaceControl,
+            long surfaceTransaction, int width, int height, int colorTopLeft, int colorTopRight,
+            int colorBottomRight, int colorBottomLeft);
+    private static native void nSurfaceTransaction_releaseBuffer(long buffer);
+    private static native void nSurfaceTransaction_setVisibility(
+            long surfaceControl, long surfaceTransaction, boolean show);
+    private static native void nSurfaceTransaction_setBufferOpaque(
+            long surfaceControl, long surfaceTransaction, boolean opaque);
+    private static native void nSurfaceTransaction_setGeometry(
+            long surfaceControl, long surfaceTransaction, int srcRight, int srcTop, int srcLeft,
+            int srcBottom, int dstRight, int dstTop, int dstLeft, int dstBottom, int transform);
+    private static native void nSurfaceTransaction_setDamageRegion(
+            long surfaceControl, long surfaceTransaction, int right, int top, int left, int bottom);
+    private static native void nSurfaceTransaction_setZOrder(
+            long surfaceControl, long surfaceTransaction, int z);
+    private static native long nSurfaceTransaction_setOnComplete(long surfaceTransaction);
+    private static native void nSurfaceTransaction_checkOnComplete(long context,
+            long desiredPresentTime);
+    private static native long nSurfaceTransaction_setDesiredPresentTime(long surfaceTransaction,
+            long desiredPresentTimeOffset);
+    private static native void nSurfaceTransaction_setBufferAlpha(long surfaceControl,
+            long surfaceTransaction, double alpha);
+    private static native void nSurfaceTransaction_reparent(long surfaceControl,
+            long newParentSurfaceControl, long surfaceTransaction);
+    private static native void nSurfaceTransaction_setColor(long surfaceControl,
+            long surfaceTransaction, float r, float g, float b, float alpha);
+}
diff --git a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
new file mode 100644
index 0000000..e02b286
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2019 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.view.cts;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+import android.view.SurfaceControl;
+import android.view.Surface;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+@LargeTest
+public class SurfaceControlTest {
+    private static final int DEFAULT_LAYOUT_WIDTH = 100;
+    private static final int DEFAULT_LAYOUT_HEIGHT = 100;
+    private static final int DEFAULT_BUFFER_WIDTH = 640;
+    private static final int DEFAULT_BUFFER_HEIGHT = 480;
+
+    @Rule
+    public ActivityTestRule<CapturedActivity> mActivityRule =
+            new ActivityTestRule<>(CapturedActivity.class);
+
+    @Rule
+    public TestName mName = new TestName();
+    private CapturedActivity mActivity;
+
+    private void verifyTest(SurfaceControlTestCase.ParentSurfaceConsumer psc,
+            PixelChecker pixelChecker) throws Throwable {
+        mActivity.verifyTest(new SurfaceControlTestCase(psc, null,
+                        pixelChecker, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                        DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT),
+                mName);
+    }
+
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+        mActivity.dismissPermissionDialog();
+    }
+
+    /**
+     * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+     * after test.
+     */
+    @After
+    public void tearDown() throws UiObjectNotFoundException {
+        mActivity.dismissPermissionDialog();
+    }
+
+    @Test
+    public void testLifecycle() {
+        final SurfaceControl.Builder b = new SurfaceControl.Builder();
+        final SurfaceControl sc = b.build();
+
+        assertTrue("Failed to build SurfaceControl", sc != null);
+        assertTrue(sc.isValid());
+        sc.release();
+        assertFalse(sc.isValid());
+    }
+
+    private SurfaceControl buildDefaultSurface(SurfaceControl parent) {
+        return new SurfaceControl.Builder()
+            .setBufferSize(DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT)
+            .setParent(parent)
+            .build();
+
+    }
+
+    void fillWithColor(SurfaceControl sc, int color) {
+        Surface s = new Surface(sc);
+
+        Canvas c = s.lockHardwareCanvas();
+        c.drawColor(color);
+        s.unlockCanvasAndPost(c);
+    }
+
+    private SurfaceControl buildDefaultRedSurface(SurfaceControl parent) {
+        final SurfaceControl sc = buildDefaultSurface(parent);
+        fillWithColor(sc, Color.RED);
+        return sc;
+    }
+
+    /**
+     * Verify that showing a 100x100 surface filled with RED produces roughly 10,000 red pixels.
+     */
+    @Test
+    public void testShow() throws Throwable {
+        verifyTest(
+                new SurfaceControlTestCase.ParentSurfaceConsumer () {
+                    @Override
+                    public void addChildren(SurfaceControl parent) {
+                        final SurfaceControl sc = buildDefaultRedSurface(parent);
+
+                        new SurfaceControl.Transaction().setVisibility(sc, true).apply();
+
+                        sc.release();
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    /**
+     * The same setup as testShow, however we hide the surface and verify that we don't see Red.
+     */
+    @Test
+    public void testHide() throws Throwable {
+        verifyTest(
+                new SurfaceControlTestCase.ParentSurfaceConsumer () {
+                    @Override
+                    public void addChildren(SurfaceControl parent) {
+                        final SurfaceControl sc = buildDefaultRedSurface(parent);
+
+                        new SurfaceControl.Transaction().setVisibility(sc, false).apply();
+
+                        sc.release();
+                    }
+                },
+                new PixelChecker(PixelColor.BLACK) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+
+    /**
+     * Here we use the same red-surface set up but construct it off-screen and then re-parent it.
+     */
+    @Test
+    public void testReparent() throws Throwable {
+        verifyTest(
+                new SurfaceControlTestCase.ParentSurfaceConsumer () {
+                    @Override
+                    public void addChildren(SurfaceControl parent) {
+                        final SurfaceControl sc = buildDefaultRedSurface(null);
+
+                        new SurfaceControl.Transaction().setVisibility(sc, true)
+                            .reparent(sc, parent)
+                            .apply();
+
+                        sc.release();
+                    }
+                },
+                new PixelChecker(PixelColor.RED) { //10000
+                    @Override
+                    public boolean checkPixels(int pixelCount, int width, int height) {
+                        return pixelCount > 9000 && pixelCount < 11000;
+                    }
+                });
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
index e3744fd..de73a79 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
@@ -15,25 +15,19 @@
  */
 package android.view.cts;
 
-import static org.junit.Assert.assertTrue;
-
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
-import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.media.MediaPlayer;
-import android.os.Environment;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.RequiresDevice;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.util.Log;
-import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
@@ -43,6 +37,7 @@
 import android.view.cts.surfacevalidator.AnimationFactory;
 import android.view.cts.surfacevalidator.AnimationTestCase;
 import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
 import android.view.cts.surfacevalidator.ViewFactory;
 import android.widget.FrameLayout;
 
@@ -53,11 +48,6 @@
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 @SuppressLint("RtlHardcoded")
@@ -190,71 +180,13 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
-    // Bad frame capture
-    ///////////////////////////////////////////////////////////////////////////
-
-    private void saveFailureCaptures(SparseArray<Bitmap> failFrames) {
-        if (failFrames.size() == 0) return;
-
-        String directoryName = Environment.getExternalStorageDirectory()
-                + "/" + getClass().getSimpleName()
-                + "/" + mName.getMethodName();
-        File testDirectory = new File(directoryName);
-        if (testDirectory.exists()) {
-            String[] children = testDirectory.list();
-            if (children == null) {
-                return;
-            }
-            for (String file : children) {
-                new File(testDirectory, file).delete();
-            }
-        } else {
-            testDirectory.mkdirs();
-        }
-
-        for (int i = 0; i < failFrames.size(); i++) {
-            int frameNr = failFrames.keyAt(i);
-            Bitmap bitmap = failFrames.valueAt(i);
-
-            String bitmapName =  "frame_" + frameNr + ".png";
-            Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + directoryName);
-
-            File file = new File(directoryName, bitmapName);
-            try (FileOutputStream fileStream = new FileOutputStream(file)) {
-                bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
-                fileStream.flush();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
     // Tests
     ///////////////////////////////////////////////////////////////////////////
 
-    private void verifyTest(AnimationTestCase testCase) throws Throwable {
-        CapturedActivity.TestResult result = mActivity.runTest(testCase);
-        saveFailureCaptures(result.failures);
-
-        float failRatio = 1.0f * result.failFrames / (result.failFrames + result.passFrames);
-        assertTrue("Error: " + failRatio + " fail ratio - extremely high, is activity obstructed?",
-                failRatio < 0.95f);
-        assertTrue("Error: " + result.failFrames
-                + " incorrect frames observed - incorrect positioning",
-                result.failFrames == 0);
-        float framesPerSecond = 1.0f * result.passFrames
-                / TimeUnit.MILLISECONDS.toSeconds(mActivity.getCaptureDurationMs());
-        assertTrue("Error, only " + result.passFrames
-                + " frames observed, virtual display only capturing at "
-                + framesPerSecond + " frames per second",
-                result.passFrames > 100);
-    }
-
     /** Draws a moving 10x10 black rectangle, validates 100 pixels of black are seen each frame */
     @Test
     public void testSmallRect() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 context -> new View(context) {
                     // draw a single pixel
                     final Paint sBlackPaint = new Paint();
@@ -273,8 +205,12 @@
                 },
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 view -> makeInfinite(ObjectAnimator.ofInt(view, "offset", 10, 30)),
-                (blackishPixelCount, width, height) ->
-                        blackishPixelCount >= 90 && blackishPixelCount <= 110));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount >= 90 && blackishPixelCount <= 110;
+                    }
+                }), mName);
     }
 
     /**
@@ -283,56 +219,80 @@
      */
     @Test
     public void testEmptySurfaceView() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sEmptySurfaceViewFactory,
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 sTranslateAnimationFactory,
-                (blackishPixelCount, width, height) ->
-                        blackishPixelCount > 9000 && blackishPixelCount < 11000));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount > 9000 && blackishPixelCount < 11000;
+                    }
+                }), mName);
     }
 
     @Test
     public void testSurfaceViewSmallScale() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sGreenSurfaceViewFactory,
                 new FrameLayout.LayoutParams(320, 240, Gravity.LEFT | Gravity.TOP),
                 sSmallScaleAnimationFactory,
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 
     @Test
     public void testSurfaceViewBigScale() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sGreenSurfaceViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
                 sBigScaleAnimationFactory,
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 
     @Test
     public void testVideoSurfaceViewTranslate() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
                 sTranslateAnimationFactory,
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 
     @Test
     public void testVideoSurfaceViewRotated() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
                 view -> makeInfinite(ObjectAnimator.ofPropertyValuesHolder(view,
                         PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 10f, 30f),
                         PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 10f, 30f),
                         PropertyValuesHolder.ofFloat(View.ROTATION, 45f, 45f))),
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 
     @Test
     public void testVideoSurfaceViewEdgeCoverage() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
                 view -> {
@@ -345,12 +305,17 @@
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_X, -x, 0, x, 0, -x),
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0, -y, 0, y, 0)));
                 },
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 
     @Test
     public void testVideoSurfaceViewCornerCoverage() throws Throwable {
-        verifyTest(new AnimationTestCase(
+        mActivity.verifyTest(new AnimationTestCase(
                 sVideoViewFactory,
                 new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
                 view -> {
@@ -363,6 +328,11 @@
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_X, -x, x, x, -x, -x),
                             PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -y, -y, y, y, -y)));
                 },
-                (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+                new PixelChecker() {
+                    @Override
+                    public boolean checkPixels(int blackishPixelCount, int width, int height) {
+                        return blackishPixelCount == 0;
+                    }
+                }), mName);
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index aec746a..66b1539 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -358,6 +358,9 @@
                     case TextureViewTest.EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
                         eglColorSpaceString = "EGL_EXT_gl_colorspace_display_p3_linear";
                         break;
+                    case TextureViewTest.EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
+                        eglColorSpaceString = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+                        break;
                     case TextureViewTest.EGL_GL_COLORSPACE_SRGB_KHR:
                         eglColorSpaceString = "EGL_KHR_gl_colorspace";
                         break;
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 53b108f..b3b8744 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -62,6 +62,7 @@
     static final int EGL_GL_COLORSPACE_LINEAR_KHR = 0x308A;
     static final int EGL_GL_COLORSPACE_DISPLAY_P3_EXT = 0x3363;
     static final int EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT = 0x3362;
+    static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
     static final int EGL_GL_COLORSPACE_SCRGB_EXT = 0x3351;
     static final int EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT = 0x3350;
 
@@ -226,6 +227,20 @@
     }
 
     @Test
+    public void testGetBitmap_8888_PassthroughP3() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
+                ColorSpace.get(ColorSpace.Named.DISPLAY_P3), false, true,
+                new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+    }
+
+    @Test
+    public void testGetBitmap_FP16_PassthroughP3() throws Throwable {
+        testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
+                ColorSpace.get(ColorSpace.Named.DISPLAY_P3), true, true,
+                new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+    }
+
+    @Test
     public void testGetBitmap_FP16_LinearP3() throws Throwable {
         ColorSpace.Rgb displayP3 = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
         ColorSpace.Rgb linearDisplayP3 = new ColorSpace.Rgb(
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index 76b1a1c..ecbb973 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -704,8 +704,6 @@
                 mPresentation.button1.getWidth() / 2,
                 mPresentation.button1.getY() + mPresentation.button1.getHeight() / 2);
         assertTrue(waitingSemaphore.tryAcquire(5, TimeUnit.SECONDS));
-
-        destroyPresentation();
     }
 
     private void checkPresentationButtonFocus(final boolean button1Focused,
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
index 74ee5ee..3ebfc79 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
@@ -20,7 +20,7 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
-public class AnimationTestCase {
+public class AnimationTestCase implements ISurfaceValidatorTestCase {
     private final ViewFactory mViewFactory;
     private final FrameLayout.LayoutParams mLayoutParams;
     private final AnimationFactory mAnimationFactory;
@@ -39,7 +39,7 @@
         mPixelChecker = pixelChecker;
     }
 
-    PixelChecker getChecker() {
+    public PixelChecker getChecker() {
         return mPixelChecker;
     }
 
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
index e1b2353..4d77ae4 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -31,6 +31,7 @@
 import android.media.projection.MediaProjection;
 import android.media.projection.MediaProjectionManager;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
@@ -47,6 +48,11 @@
 import android.view.cts.R;
 import android.widget.FrameLayout;
 
+import org.junit.rules.TestName;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -160,7 +166,7 @@
         return mOnEmbedded ? 100000 : 10000;
     }
 
-    public TestResult runTest(AnimationTestCase animationTestCase) throws Throwable {
+    public TestResult runTest(ISurfaceValidatorTestCase animationTestCase) throws Throwable {
         TestResult testResult = new TestResult();
         if (mOnWatch) {
             /**
@@ -260,6 +266,61 @@
         return testResult;
     }
 
+    private void saveFailureCaptures(SparseArray<Bitmap> failFrames, TestName name) {
+        if (failFrames.size() == 0) return;
+
+        String directoryName = Environment.getExternalStorageDirectory()
+                + "/" + getClass().getSimpleName()
+                + "/" + name.getMethodName();
+        File testDirectory = new File(directoryName);
+        if (testDirectory.exists()) {
+            String[] children = testDirectory.list();
+            if (children == null) {
+                return;
+            }
+            for (String file : children) {
+                new File(testDirectory, file).delete();
+            }
+        } else {
+            testDirectory.mkdirs();
+        }
+
+        for (int i = 0; i < failFrames.size(); i++) {
+            int frameNr = failFrames.keyAt(i);
+            Bitmap bitmap = failFrames.valueAt(i);
+
+            String bitmapName =  "frame_" + frameNr + ".png";
+            Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + directoryName);
+
+            File file = new File(directoryName, bitmapName);
+            try (FileOutputStream fileStream = new FileOutputStream(file)) {
+                bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
+                fileStream.flush();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void verifyTest(ISurfaceValidatorTestCase testCase, TestName name) throws Throwable {
+        CapturedActivity.TestResult result = runTest(testCase);
+        saveFailureCaptures(result.failures, name);
+
+        float failRatio = 1.0f * result.failFrames / (result.failFrames + result.passFrames);
+        assertTrue("Error: " + failRatio + " fail ratio - extremely high, is activity obstructed?",
+                failRatio < 0.95f);
+        assertTrue("Error: " + result.failFrames
+                        + " incorrect frames observed - incorrect positioning",
+                result.failFrames == 0);
+
+        float framesPerSecond = 1.0f * result.passFrames
+                / TimeUnit.MILLISECONDS.toSeconds(getCaptureDurationMs());
+        assertTrue("Error, only " + result.passFrames
+                        + " frames observed, virtual display only capturing at "
+                        + framesPerSecond + " frames per second",
+                result.passFrames > 100);
+    }
+
     private class MediaProjectionCallback extends MediaProjection.Callback {
         @Override
         public void onStop() {
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
new file mode 100644
index 0000000..3b74958
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.cts.surfacevalidator;
+
+import android.content.Context;
+import android.widget.FrameLayout;
+
+public interface ISurfaceValidatorTestCase {
+    PixelChecker getChecker();
+
+    void start(Context context, FrameLayout parent);
+
+    void end();
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
index 76f0adc..860d11b 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
@@ -15,6 +15,20 @@
  */
 package android.view.cts.surfacevalidator;
 
-public interface PixelChecker {
-    boolean checkPixels(int blackishPixelCount, int width, int height);
-}
\ No newline at end of file
+public abstract class PixelChecker {
+    private PixelColor mPixelColor;
+
+    public PixelChecker() {
+        mPixelColor = new PixelColor();
+    }
+
+    public PixelChecker(int color) {
+        mPixelColor = new PixelColor(color);
+    }
+
+    PixelColor getColor() {
+        return mPixelColor;
+    }
+
+    public abstract boolean checkPixels(int matchingPixelCount, int width, int height);
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
new file mode 100644
index 0000000..a7395bb
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 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.view.cts.surfacevalidator;
+
+public class PixelColor {
+    public static final int BLACK = 0xFF000000;
+    public static final int RED = 0xFF0000FF;
+    public static final int GREEN = 0xFF00FF00;
+    public static final int BLUE = 0xFFFF0000;
+
+    public static final int TRANSPARENT_RED = 0x7F0000FF;
+
+    // Default to black
+    public short mMinAlpha;
+    public short mMaxAlpha;
+    public short mMinRed;
+    public short mMaxRed;
+    public short mMinBlue;
+    public short mMaxBlue;
+    public short mMinGreen;
+    public short mMaxGreen;
+
+    public PixelColor(int color) {
+        short alpha = (short) ((color >> 24) & 0xFF);
+        short blue = (short) ((color >> 16) & 0xFF);
+        short green = (short) ((color >> 8) & 0xFF);
+        short red = (short) (color & 0xFF);
+
+        mMinAlpha = (short) getMinValue(alpha);
+        mMaxAlpha = (short) getMaxValue(alpha);
+        mMinRed = (short) getMinValue(red);
+        mMaxRed = (short) getMaxValue(red);
+        mMinBlue = (short) getMinValue(blue);
+        mMaxBlue = (short) getMaxValue(blue);
+        mMinGreen = (short) getMinValue(green);
+        mMaxGreen = (short) getMaxValue(green);
+    }
+
+    public PixelColor() {
+        this(BLACK);
+    }
+
+    private int getMinValue(short color) {
+        if (color - 4 > 0) {
+            return color - 4;
+        }
+        return 0;
+    }
+
+    private int getMaxValue(short color) {
+        if (color + 4 < 0xFF) {
+            return color + 4;
+        }
+        return 0xFF;
+    }
+
+    public void addToPixelCounter(ScriptC_PixelCounter script) {
+        script.set_MIN_ALPHA(mMinAlpha);
+        script.set_MAX_ALPHA(mMaxAlpha);
+        script.set_MIN_RED(mMinRed);
+        script.set_MAX_RED(mMaxRed);
+        script.set_MIN_BLUE(mMinBlue);
+        script.set_MAX_BLUE(mMaxBlue);
+        script.set_MIN_GREEN(mMinGreen);
+        script.set_MAX_GREEN(mMaxGreen);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
index 12e024c..b4fe3be 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
@@ -17,14 +17,26 @@
 #pragma rs java_package_name(android.view.cts.surfacevalidator)
 #pragma rs reduce(countBlackishPixels) accumulator(countBlackishPixelsAccum) combiner(countBlackishPixelsCombiner)
 
-uchar THRESHOLD;
+uchar MIN_ALPHA;
+uchar MAX_ALPHA;
+uchar MIN_RED;
+uchar MAX_RED;
+uchar MIN_GREEN;
+uchar MAX_GREEN;
+uchar MIN_BLUE;
+uchar MAX_BLUE;
 int BOUNDS[4];
 
 static void countBlackishPixelsAccum(int *accum, uchar4 pixel, uint32_t x, uint32_t y) {
 
-    if (pixel.r < THRESHOLD
-            && pixel.g < THRESHOLD
-            && pixel.b < THRESHOLD
+    if (pixel.a <= MAX_ALPHA
+            && pixel.a >= MIN_ALPHA
+            && pixel.r <= MAX_RED
+            && pixel.r >= MIN_RED
+            && pixel.g <= MAX_GREEN
+            && pixel.g >= MIN_GREEN
+            && pixel.b <= MAX_BLUE
+            && pixel.b >= MIN_BLUE
             && x >= BOUNDS[0]
             && x < BOUNDS[2]
             && y >= BOUNDS[1]
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
new file mode 100644
index 0000000..9c8c871
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.cts.surfacevalidator;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.view.Gravity;
+import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class SurfaceControlTestCase implements ISurfaceValidatorTestCase {
+    private final SurfaceViewFactory mViewFactory;
+    private final FrameLayout.LayoutParams mLayoutParams;
+    private final AnimationFactory mAnimationFactory;
+    private final PixelChecker mPixelChecker;
+    
+    private final int mBufferWidth;
+    private final int mBufferHeight;
+
+    private FrameLayout mParent;
+    private ValueAnimator mAnimator;
+
+    public static abstract class ParentSurfaceConsumer {
+        abstract public void addChildren(SurfaceControl parent);
+    };
+
+    private static class ParentSurfaceHolder implements SurfaceHolder.Callback {
+        ParentSurfaceConsumer mPsc;
+        SurfaceView mSurfaceView;
+
+        ParentSurfaceHolder(ParentSurfaceConsumer psc) {
+            mPsc = psc;
+        }
+
+        public void surfaceCreated(SurfaceHolder holder) {
+            mPsc.addChildren(mSurfaceView.getSurfaceControl());
+        }
+        public void surfaceDestroyed(SurfaceHolder holder) {
+        }
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        }
+    };
+
+    public SurfaceControlTestCase(SurfaceHolder.Callback callback,
+            AnimationFactory animationFactory, PixelChecker pixelChecker,
+            int layoutWidth, int layoutHeight, int bufferWidth, int bufferHeight) {
+        mViewFactory = new SurfaceViewFactory(callback);
+        mLayoutParams =
+                new FrameLayout.LayoutParams(layoutWidth, layoutHeight, Gravity.LEFT | Gravity.TOP);
+        mAnimationFactory = animationFactory;
+        mPixelChecker = pixelChecker;
+        mBufferWidth = bufferWidth;
+        mBufferHeight = bufferHeight;
+    }
+
+    public SurfaceControlTestCase(ParentSurfaceConsumer psc,
+            AnimationFactory animationFactory, PixelChecker pixelChecker,
+            int layoutWidth, int layoutHeight, int bufferWidth, int bufferHeight) {
+        this(new ParentSurfaceHolder(psc), animationFactory, pixelChecker,
+                layoutWidth, layoutHeight, bufferWidth, bufferHeight);
+    }
+
+    public PixelChecker getChecker() {
+        return mPixelChecker;
+    }
+
+    public void start(Context context, FrameLayout parent) {
+        View view = mViewFactory.createView(context);
+        if (mViewFactory.mCallback instanceof ParentSurfaceHolder) {
+            ParentSurfaceHolder psh = (ParentSurfaceHolder) mViewFactory.mCallback;
+            psh.mSurfaceView = (SurfaceView) view;
+        }
+
+        mParent = parent;
+        mParent.addView(view, mLayoutParams);
+
+        if (mAnimationFactory != null) {
+            mAnimator = mAnimationFactory.createAnimator(view);
+            mAnimator.start();
+        }
+    }
+
+    public void end() {
+        if (mAnimator != null) {
+            mAnimator.end();
+            mAnimator = null;
+        }
+        mParent.removeAllViews();
+    }
+
+    private class SurfaceViewFactory implements ViewFactory {
+        private SurfaceHolder.Callback mCallback;
+
+        SurfaceViewFactory(SurfaceHolder.Callback callback) {
+            mCallback = callback;
+        }
+
+        public View createView(Context context) {
+            SurfaceView surfaceView = new SurfaceView(context);
+
+            // prevent transparent region optimization, which is invalid for a SurfaceView moving
+            // around
+            surfaceView.setWillNotDraw(false);
+
+            surfaceView.getHolder().setFixedSize(mBufferWidth, mBufferHeight);
+            surfaceView.getHolder().addCallback(mCallback);
+
+            return surfaceView;
+        }
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
index 1a8bc0db..c2fb007 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
@@ -39,9 +39,6 @@
      */
     private static final int NUM_FIRST_FRAMES_SKIPPED = 8;
 
-    // If no channel is greater than this value, pixel will be considered 'blackish'.
-    private static final short PIXEL_CHANNEL_THRESHOLD = 4;
-
     private static final int MAX_CAPTURED_FAILURES = 5;
 
     private final int mWidth;
@@ -120,7 +117,7 @@
         mInPixelsAllocation = createBufferQueueAllocation();
         mScript.set_BOUNDS(new int[] {boundsToCheck.left, boundsToCheck.top,
                 boundsToCheck.right, boundsToCheck.bottom});
-        mScript.set_THRESHOLD(PIXEL_CHANNEL_THRESHOLD);
+        pixelChecker.getColor().addToPixelCounter(mScript);
 
         mInPixelsAllocation.setOnBufferAvailableListener(
                 allocation -> mWorkerHandler.post(mConsumeRunnable));
diff --git a/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java b/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
index 6729491..98c8dd7 100644
--- a/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
+++ b/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -27,19 +27,46 @@
 import org.junit.runner.RunWith;
 
 /**
- * Tests for {@link IntEnumMapping}
+ * Tests for {@link IntEnumMapping}.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public final class IntEnumMappingTest {
+public class IntEnumMappingTest {
     @Test
-    public void testMapping() {
+    public void testSimpleValue() {
         IntEnumMapping mapping = new IntEnumMapping.Builder()
-                .addValue("ONE", 1)
-                .addValue("TWO", 2)
+                .addValue("ZERO", 0)
                 .build();
-        assertNull(mapping.nameOf(0));
-        assertEquals("ONE", mapping.nameOf(1));
-        assertEquals("TWO", mapping.nameOf(2));
+        assertEquals("ZERO", mapping.get(0));
+    }
+
+    @Test
+    public void testMissingValue() {
+        IntEnumMapping mapping = new IntEnumMapping.Builder()
+                .addValue("ZERO", 0)
+                .build();
+        assertNull(mapping.get(1));
+    }
+
+    @Test
+    public void testBuilderReuse() {
+        IntEnumMapping.Builder builder = new IntEnumMapping.Builder();
+
+        builder.addValue("ONE", 1);
+        IntEnumMapping mapping1 = builder.build();
+
+        assertEquals("ONE", mapping1.get(1));
+
+        builder.addValue("TWO", 2);
+        IntEnumMapping mapping2 = builder.build();
+
+        assertEquals("ONE", mapping2.get(1));
+        assertEquals("TWO", mapping2.get(2));
+        assertNull(mapping1.get(2));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullName() {
+        new IntEnumMapping.Builder().addValue(null, 0);
     }
 }
diff --git a/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java b/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
index ba3a3af..ce93d30 100644
--- a/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
+++ b/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
@@ -16,7 +16,8 @@
 
 package android.view.inspector.cts;
 
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -25,8 +26,14 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
- * Tests for {@link IntFlagMapping}
+ * Tests for {@link IntFlagMapping}.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -38,11 +45,11 @@
                 .addFlag("TWO", 2)
                 .build();
 
-        assertArrayEquals(new String[0], mapping.namesOf(0));
-        assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
-        assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
-        assertArrayEquals(new String[] {"ONE", "TWO"}, mapping.namesOf(3));
-        assertArrayEquals(new String[0], mapping.namesOf(4));
+        assertEmpty(mapping.get(0));
+        assertEquals(setOf("ONE"), mapping.get(1));
+        assertEquals(setOf("TWO"), mapping.get(2));
+        assertEquals(setOf("ONE", "TWO"), mapping.get(3));
+        assertEmpty(mapping.get(4));
     }
 
     @Test
@@ -53,11 +60,11 @@
                 .build();
 
 
-        assertArrayEquals(new String[0], mapping.namesOf(0));
-        assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
-        assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
-        assertArrayEquals(new String[0], mapping.namesOf(3));
-        assertArrayEquals(new String[0], mapping.namesOf(4));
+        assertEmpty(mapping.get(0));
+        assertEquals(setOf("ONE"), mapping.get(1));
+        assertEquals(setOf("TWO"), mapping.get(2));
+        assertEmpty(mapping.get(3));
+        assertEmpty(mapping.get(4));
     }
 
     @Test
@@ -69,13 +76,28 @@
                 .build();
 
 
-        assertArrayEquals(new String[0], mapping.namesOf(0));
-        assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
-        assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
-        assertArrayEquals(new String[0], mapping.namesOf(3));
-        assertArrayEquals(new String[] {"FOUR"}, mapping.namesOf(4));
-        assertArrayEquals(new String[] {"ONE", "FOUR"}, mapping.namesOf(5));
-        assertArrayEquals(new String[] {"TWO", "FOUR"}, mapping.namesOf(6));
-        assertArrayEquals(new String[] {"FOUR"}, mapping.namesOf(7));
+        assertEmpty(mapping.get(0));
+        assertEquals(setOf("ONE"), mapping.get(1));
+        assertEquals(setOf("TWO"), mapping.get(2));
+        assertEmpty(mapping.get(3));
+        assertEquals(setOf("FOUR"), mapping.get(4));
+        assertEquals(setOf("ONE", "FOUR"), mapping.get(5));
+        assertEquals(setOf("TWO", "FOUR"), mapping.get(6));
+        assertEquals(setOf("FOUR"), mapping.get(7));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullName() {
+        new IntFlagMapping.Builder().addFlag(null, 0);
+    }
+
+    private static Set<String> setOf(String... values) {
+        final Set<String> set = new HashSet<>(values.length);
+        set.addAll(Arrays.asList(values));
+        return Collections.unmodifiableSet(set);
+    }
+
+    private static void assertEmpty(Collection collection) {
+        assertTrue(collection.isEmpty());
     }
 }
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
index 54f6166..8e34571 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
@@ -29,7 +29,9 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.view.textclassifier.ConversationAction;
 import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassifier;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -97,16 +99,16 @@
 
     @Test
     public void testTypeConfig_full() {
-        ConversationActions.TypeConfig typeConfig =
-                new ConversationActions.TypeConfig.Builder()
+        TextClassifier.EntityConfig typeConfig =
+                new TextClassifier.EntityConfig.Builder()
                         .setIncludedTypes(
-                                Collections.singletonList(ConversationActions.TYPE_OPEN_URL))
+                                Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
                         .setExcludedTypes(
-                                Collections.singletonList(ConversationActions.TYPE_CALL_PHONE))
+                                Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
                         .build();
 
-        ConversationActions.TypeConfig recovered =
-                parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+        TextClassifier.EntityConfig recovered =
+                parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
 
         assertFullTypeConfig(typeConfig);
         assertFullTypeConfig(recovered);
@@ -114,17 +116,17 @@
 
     @Test
     public void testTypeConfig_full_notIncludeTypesFromTextClassifier() {
-        ConversationActions.TypeConfig typeConfig =
-                new ConversationActions.TypeConfig.Builder()
+        TextClassifier.EntityConfig typeConfig =
+                new TextClassifier.EntityConfig.Builder()
                         .includeTypesFromTextClassifier(false)
                         .setIncludedTypes(
-                                Collections.singletonList(ConversationActions.TYPE_OPEN_URL))
+                                Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
                         .setExcludedTypes(
-                                Collections.singletonList(ConversationActions.TYPE_CALL_PHONE))
+                                Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
                         .build();
 
-        ConversationActions.TypeConfig recovered =
-                parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+        TextClassifier.EntityConfig recovered =
+                parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
 
         assertFullTypeConfig_notIncludeTypesFromTextClassifier(typeConfig);
         assertFullTypeConfig_notIncludeTypesFromTextClassifier(recovered);
@@ -132,11 +134,11 @@
 
     @Test
     public void testTypeConfig_minimal() {
-        ConversationActions.TypeConfig typeConfig =
-                new ConversationActions.TypeConfig.Builder().build();
+        TextClassifier.EntityConfig typeConfig =
+                new TextClassifier.EntityConfig.Builder().build();
 
-        ConversationActions.TypeConfig recovered =
-                parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+        TextClassifier.EntityConfig recovered =
+                parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
 
         assertMinimalTypeConfig(typeConfig);
         assertMinimalTypeConfig(recovered);
@@ -166,14 +168,16 @@
                 new ConversationActions.Message.Builder(PERSON)
                         .setText(TEXT)
                         .build();
-        ConversationActions.TypeConfig typeConfig =
-                new ConversationActions.TypeConfig.Builder()
+        TextClassifier.EntityConfig typeConfig =
+                new TextClassifier.EntityConfig.Builder()
                         .includeTypesFromTextClassifier(false)
                         .build();
         ConversationActions.Request request =
                 new ConversationActions.Request.Builder(Collections.singletonList(message))
                         .setConversationId(CONVERSATION_ID)
-                        .setHints(Collections.singletonList(ConversationActions.HINT_FOR_IN_APP))
+                        .setHints(
+                                Collections.singletonList(
+                                        ConversationActions.Request.HINT_FOR_IN_APP))
                         .setMaxSuggestions(10)
                         .setTypeConfig(typeConfig)
                         .build();
@@ -187,14 +191,14 @@
 
     @Test
     public void testConversationAction_minimal() {
-        ConversationActions.ConversationAction conversationAction =
-                new ConversationActions.ConversationAction.Builder(
-                        ConversationActions.TYPE_CALL_PHONE)
+        ConversationAction conversationAction =
+                new ConversationAction.Builder(
+                        ConversationAction.TYPE_CALL_PHONE)
                         .build();
 
-        ConversationActions.ConversationAction recovered =
+        ConversationAction recovered =
                 parcelizeDeparcelize(conversationAction,
-                        ConversationActions.ConversationAction.CREATOR);
+                        ConversationAction.CREATOR);
 
         assertMinimalConversationAction(conversationAction);
         assertMinimalConversationAction(recovered);
@@ -202,18 +206,18 @@
 
     @Test
     public void testConversationAction_full() {
-        ConversationActions.ConversationAction conversationAction =
-                new ConversationActions.ConversationAction.Builder(
-                        ConversationActions.TYPE_CALL_PHONE)
+        ConversationAction conversationAction =
+                new ConversationAction.Builder(
+                        ConversationAction.TYPE_CALL_PHONE)
                         .setConfidenceScore(1.0f)
                         .setTextReply(TEXT)
                         .setAction(REMOTE_ACTION)
                         .setExtras(EXTRAS)
                         .build();
 
-        ConversationActions.ConversationAction recovered =
+        ConversationAction recovered =
                 parcelizeDeparcelize(conversationAction,
-                        ConversationActions.ConversationAction.CREATOR);
+                        ConversationAction.CREATOR);
 
         assertFullConversationAction(conversationAction);
         assertFullConversationAction(recovered);
@@ -221,9 +225,9 @@
 
     @Test
     public void testConversationActions_full() {
-        ConversationActions.ConversationAction conversationAction =
-                new ConversationActions.ConversationAction.Builder(
-                        ConversationActions.TYPE_CALL_PHONE)
+        ConversationAction conversationAction =
+                new ConversationAction.Builder(
+                        ConversationAction.TYPE_CALL_PHONE)
                         .build();
 
         ConversationActions conversationActions =
@@ -238,9 +242,9 @@
 
     @Test
     public void testConversationActions_minimal() {
-        ConversationActions.ConversationAction conversationAction =
-                new ConversationActions.ConversationAction.Builder(
-                        ConversationActions.TYPE_CALL_PHONE)
+        ConversationAction conversationAction =
+                new ConversationAction.Builder(
+                        ConversationAction.TYPE_CALL_PHONE)
                         .build();
 
         ConversationActions conversationActions =
@@ -266,40 +270,42 @@
         assertThat(message.getReferenceTime()).isNull();
     }
 
-    private void assertFullTypeConfig(ConversationActions.TypeConfig typeConfig) {
+    private void assertFullTypeConfig(TextClassifier.EntityConfig typeConfig) {
         List<String> extraTypesFromTextClassifier = Arrays.asList(
-                ConversationActions.TYPE_CALL_PHONE,
-                ConversationActions.TYPE_CREATE_REMINDER);
+                ConversationAction.TYPE_CALL_PHONE,
+                ConversationAction.TYPE_CREATE_REMINDER);
 
-        Collection<String> resolvedTypes = typeConfig.resolveTypes(extraTypesFromTextClassifier);
+        Collection<String> resolvedTypes =
+                typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
 
         assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
-        assertThat(typeConfig.resolveTypes(Collections.emptyList()))
-                .containsExactly(ConversationActions.TYPE_OPEN_URL);
+        assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
+                .containsExactly(ConversationAction.TYPE_OPEN_URL);
         assertThat(resolvedTypes).containsExactly(
-                ConversationActions.TYPE_OPEN_URL, ConversationActions.TYPE_CREATE_REMINDER);
+                ConversationAction.TYPE_OPEN_URL, ConversationAction.TYPE_CREATE_REMINDER);
     }
 
     private void assertFullTypeConfig_notIncludeTypesFromTextClassifier(
-            ConversationActions.TypeConfig typeConfig) {
+            TextClassifier.EntityConfig typeConfig) {
         List<String> extraTypesFromTextClassifier = Arrays.asList(
-                ConversationActions.TYPE_CALL_PHONE,
-                ConversationActions.TYPE_CREATE_REMINDER);
+                ConversationAction.TYPE_CALL_PHONE,
+                ConversationAction.TYPE_CREATE_REMINDER);
 
-        Collection<String> resolvedTypes = typeConfig.resolveTypes(extraTypesFromTextClassifier);
+        Collection<String> resolvedTypes =
+                typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
 
         assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isFalse();
-        assertThat(typeConfig.resolveTypes(Collections.emptyList()))
-                .containsExactly(ConversationActions.TYPE_OPEN_URL);
-        assertThat(resolvedTypes).containsExactly(ConversationActions.TYPE_OPEN_URL);
+        assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
+                .containsExactly(ConversationAction.TYPE_OPEN_URL);
+        assertThat(resolvedTypes).containsExactly(ConversationAction.TYPE_OPEN_URL);
     }
 
-    private void assertMinimalTypeConfig(ConversationActions.TypeConfig typeConfig) {
+    private void assertMinimalTypeConfig(TextClassifier.EntityConfig typeConfig) {
         assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
-        assertThat(typeConfig.resolveTypes(Collections.emptyList())).isEmpty();
-        assertThat(typeConfig.resolveTypes(
-                Collections.singletonList(ConversationActions.TYPE_OPEN_URL))).containsExactly(
-                ConversationActions.TYPE_OPEN_URL);
+        assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList())).isEmpty();
+        assertThat(typeConfig.resolveEntityListModifications(
+                Collections.singletonList(ConversationAction.TYPE_OPEN_URL))).containsExactly(
+                ConversationAction.TYPE_OPEN_URL);
     }
 
     private void assertMinimalRequest(ConversationActions.Request request) {
@@ -316,24 +322,24 @@
         assertThat(request.getConversation()).hasSize(1);
         assertThat(request.getConversation().get(0).getText().toString()).isEqualTo(TEXT);
         assertThat(request.getConversation().get(0).getAuthor()).isEqualTo(PERSON);
-        assertThat(request.getHints()).containsExactly(ConversationActions.HINT_FOR_IN_APP);
+        assertThat(request.getHints()).containsExactly(ConversationActions.Request.HINT_FOR_IN_APP);
         assertThat(request.getMaxSuggestions()).isEqualTo(10);
         assertThat(request.getTypeConfig().shouldIncludeTypesFromTextClassifier()).isFalse();
         assertThat(request.getConversationId()).isEqualTo(CONVERSATION_ID);
     }
 
     private void assertMinimalConversationAction(
-            ConversationActions.ConversationAction conversationAction) {
+            ConversationAction conversationAction) {
         assertThat(conversationAction.getAction()).isNull();
         assertThat(conversationAction.getConfidenceScore()).isWithin(FLOAT_TOLERANCE).of(0.0f);
-        assertThat(conversationAction.getType()).isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+        assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_CALL_PHONE);
     }
 
     private void assertFullConversationAction(
-            ConversationActions.ConversationAction conversationAction) {
+            ConversationAction conversationAction) {
         assertThat(conversationAction.getAction().getTitle()).isEqualTo(TEXT);
         assertThat(conversationAction.getConfidenceScore()).isWithin(FLOAT_TOLERANCE).of(1.0f);
-        assertThat(conversationAction.getType()).isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+        assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_CALL_PHONE);
         assertThat(conversationAction.getTextReply()).isEqualTo(TEXT);
         assertThat(conversationAction.getExtras().keySet()).containsExactly(TEXT);
     }
@@ -341,14 +347,14 @@
     private void assertMinimalConversationActions(ConversationActions conversationActions) {
         assertThat(conversationActions.getConversationActions()).hasSize(1);
         assertThat(conversationActions.getConversationActions().get(0).getType())
-                .isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+                .isEqualTo(ConversationAction.TYPE_CALL_PHONE);
         assertThat(conversationActions.getId()).isNull();
     }
 
     private void assertFullConversationActions(ConversationActions conversationActions) {
         assertThat(conversationActions.getConversationActions()).hasSize(1);
         assertThat(conversationActions.getConversationActions().get(0).getType())
-                .isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+                .isEqualTo(ConversationAction.TYPE_CALL_PHONE);
         assertThat(conversationActions.getId()).isEqualTo(ID);
     }
 
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
index 1cd65b8..3a33b86 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
@@ -30,6 +30,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.view.textclassifier.ConversationAction;
 import android.view.textclassifier.ConversationActions;
 import android.view.textclassifier.SelectionEvent;
 import android.view.textclassifier.TextClassification;
@@ -80,12 +81,17 @@
             new TextLanguage.Request.Builder(TEXT)
                     .setExtras(BUNDLE)
                     .build();
-    private static final ConversationActions.Message MESSAGE =
-            new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_REMOTE)
+    private static final ConversationActions.Message FIRST_MESSAGE =
+            new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_SELF)
+                    .setText(TEXT)
+                    .build();
+    private static final ConversationActions.Message SECOND_MESSAGE =
+            new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
                     .setText(TEXT)
                     .build();
     private static final ConversationActions.Request CONVERSATION_ACTIONS_REQUEST =
-            new ConversationActions.Request.Builder(Arrays.asList(MESSAGE)).build();
+            new ConversationActions.Request.Builder(
+                    Arrays.asList(FIRST_MESSAGE, SECOND_MESSAGE)).build();
 
     private TextClassificationManager mManager;
     private TextClassifier mClassifier;
@@ -273,10 +279,10 @@
 
     private static void assertValidResult(ConversationActions conversationActions) {
         assertNotNull(conversationActions);
-        List<ConversationActions.ConversationAction> conversationActionsList =
+        List<ConversationAction> conversationActionsList =
                 conversationActions.getConversationActions();
         assertNotNull(conversationActionsList);
-        for (ConversationActions.ConversationAction conversationAction : conversationActionsList) {
+        for (ConversationAction conversationAction : conversationActionsList) {
             assertThat(conversationAction.getAction()).isNotNull();
             assertThat(conversationAction.getType()).isNotNull();
             assertThat(conversationAction.getConfidenceScore()).isGreaterThan(0f);
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java b/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
index f1ca661..f84f2bf 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
@@ -20,7 +20,6 @@
 
 import android.os.Bundle;
 import android.os.Parcel;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.textclassifier.TextClassificationContext;
@@ -34,18 +33,108 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class TextClassifierEventTest {
+    private static final float TOLERANCE = 0.000001f;
 
     @Test
     public void testMinimumEvent() {
-        final TextClassifierEvent event = new TextClassifierEvent.Builder(
+        final TextClassifierEvent event = createMinimalTextClassifierEvent();
+
+        assertMinimalTextClassifierEvent(event);
+    }
+
+    @Test
+    public void testParcelUnparcel_minimumEvent() {
+        final TextClassifierEvent event = createMinimalTextClassifierEvent();
+
+        final Parcel parcel = Parcel.obtain();
+        event.writeToParcel(parcel, event.describeContents());
+        parcel.setDataPosition(0);
+        final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
+
+        assertMinimalTextClassifierEvent(result);
+    }
+
+    @Test
+    public void testFullEvent() {
+        final long eventTime = System.currentTimeMillis();
+        final TextClassifierEvent event = createFullTextClassifierEvent(eventTime);
+
+        assertFullEvent(event, eventTime);
+    }
+
+    @Test
+    public void testParcelUnparcel_fullEvent() {
+        final long eventTime = System.currentTimeMillis();
+        final TextClassifierEvent event = createFullTextClassifierEvent(eventTime);
+
+        final Parcel parcel = Parcel.obtain();
+        event.writeToParcel(parcel, event.describeContents());
+        parcel.setDataPosition(0);
+        final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
+
+        assertFullEvent(result, eventTime);
+    }
+
+    private TextClassifierEvent createFullTextClassifierEvent(long eventTime) {
+        final Bundle extra = new Bundle();
+        extra.putString("key", "value");
+        return new TextClassifierEvent.Builder(
+                TextClassifierEvent.CATEGORY_LINKIFY,
+                TextClassifierEvent.TYPE_LINK_CLICKED)
+                .setEventIndex(2)
+                .setEventTime(eventTime)
+                .setEntityTypes(TextClassifier.TYPE_ADDRESS)
+                .setRelativeWordStartIndex(1)
+                .setRelativeWordEndIndex(2)
+                .setRelativeSuggestedWordStartIndex(-1)
+                .setRelativeSuggestedWordEndIndex(3)
+                .setLanguage("en")
+                .setResultId("androidtc-en-v606-1234")
+                .setActionIndices(1, 2, 5)
+                .setExtras(extra)
+                .setEventContext(new TextClassificationContext.Builder(
+                        "pkg", TextClassifier.WIDGET_TYPE_TEXTVIEW)
+                        .setWidgetVersion(TextView.class.getName())
+                        .build())
+                .setScore(0.5f)
+                .setEntityTypes(TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_DATE)
+                .build();
+    }
+
+    private void assertFullEvent(TextClassifierEvent event, long expectedEventTime) {
+        assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_LINKIFY);
+        assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_LINK_CLICKED);
+        assertThat(event.getEventIndex()).isEqualTo(2);
+        assertThat(event.getEventTime()).isEqualTo(expectedEventTime);
+        assertThat(event.getEntityTypes()).asList()
+                .containsExactly(TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_DATE);
+        assertThat(event.getRelativeWordStartIndex()).isEqualTo(1);
+        assertThat(event.getRelativeWordEndIndex()).isEqualTo(2);
+        assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
+        assertThat(event.getRelativeSuggestedWordEndIndex()).isEqualTo(3);
+        assertThat(event.getLanguage()).isEqualTo("en");
+        assertThat(event.getResultId()).isEqualTo("androidtc-en-v606-1234");
+        assertThat(event.getActionIndices()).asList().containsExactly(1, 2, 5);
+        assertThat(event.getExtras().get("key")).isEqualTo("value");
+        assertThat(event.getEventContext().getPackageName()).isEqualTo("pkg");
+        assertThat(event.getEventContext().getWidgetType())
+                .isEqualTo(TextClassifier.WIDGET_TYPE_TEXTVIEW);
+        assertThat(event.getEventContext().getWidgetVersion()).isEqualTo(TextView.class.getName());
+        assertThat(event.getScore()).isWithin(TOLERANCE).of(0.5f);
+    }
+
+    private TextClassifierEvent createMinimalTextClassifierEvent() {
+        return new TextClassifierEvent.Builder(
                 TextClassifierEvent.CATEGORY_UNDEFINED, TextClassifierEvent.TYPE_UNDEFINED)
                 .build();
+    }
 
+    private void assertMinimalTextClassifierEvent(TextClassifierEvent event) {
         assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_UNDEFINED);
         assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_UNDEFINED);
         assertThat(event.getEventIndex()).isEqualTo(0);
         assertThat(event.getEventTime()).isEqualTo(0);
-        assertThat(event.getEntityType()).isNull();
+        assertThat(event.getEntityTypes()).isEmpty();
         assertThat(event.getRelativeWordStartIndex()).isEqualTo(0);
         assertThat(event.getRelativeWordEndIndex()).isEqualTo(0);
         assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(0);
@@ -53,102 +142,8 @@
         assertThat(event.getLanguage()).isNull();
         assertThat(event.getResultId()).isNull();
         assertThat(event.getActionIndices()).isEmpty();
-        assertThat(event.getExtras()).isEqualTo(Bundle.EMPTY);
+        assertThat(event.getExtras().size()).isEqualTo(0);
         assertThat(event.getEventContext()).isNull();
-    }
-
-    @Test
-    public void testFullEvent() {
-        final Bundle extra = new Bundle();
-        extra.putString("key", "value");
-        final long now = System.currentTimeMillis();
-        final String resultId = "androidtc-en-v606-1234";
-        final TextClassifierEvent event = new TextClassifierEvent.Builder(
-                TextClassifierEvent.CATEGORY_LINKIFY,
-                TextClassifierEvent.TYPE_LINK_CLICKED)
-                .setEventIndex(2)
-                .setEventTime(now)
-                .setEntityType(TextClassifier.TYPE_ADDRESS)
-                .setRelativeWordStartIndex(1)
-                .setRelativeWordEndIndex(2)
-                .setRelativeSuggestedWordStartIndex(-1)
-                .setRelativeSuggestedWordEndIndex(3)
-                .setLanguage("en")
-                .setResultId(resultId)
-                .setActionIndices(1, 2, 5)
-                .setExtras(extra)
-                .setEventContext(new TextClassificationContext.Builder(
-                        "pkg", TextClassifier.WIDGET_TYPE_TEXTVIEW)
-                        .setWidgetVersion(TextView.class.getName())
-                        .build())
-                .build();
-
-        assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_LINKIFY);
-        assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_LINK_CLICKED);
-        assertThat(event.getEventIndex()).isEqualTo(2);
-        assertThat(event.getEventTime()).isEqualTo(now);
-        assertThat(event.getEntityType()).isEqualTo(TextClassifier.TYPE_ADDRESS);
-        assertThat(event.getRelativeWordStartIndex()).isEqualTo(1);
-        assertThat(event.getRelativeWordEndIndex()).isEqualTo(2);
-        assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
-        assertThat(event.getRelativeSuggestedWordEndIndex()).isEqualTo(3);
-        assertThat(event.getLanguage()).isEqualTo("en");
-        assertThat(event.getResultId()).isEqualTo(resultId);
-        assertThat(event.getActionIndices()).asList().containsExactly(1, 2, 5);
-        assertThat(event.getExtras().get("key")).isEqualTo("value");
-        assertThat(event.getEventContext().getPackageName()).isEqualTo("pkg");
-        assertThat(event.getEventContext().getWidgetType())
-                .isEqualTo(TextClassifier.WIDGET_TYPE_TEXTVIEW);
-        assertThat(event.getEventContext().getWidgetVersion()).isEqualTo(TextView.class.getName());
-    }
-
-    @Test
-    public void testParcelUnparcel() {
-        final Bundle extra = new Bundle();
-        extra.putString("k", "v");
-        final TextClassifierEvent event = new TextClassifierEvent.Builder(
-                TextClassifierEvent.CATEGORY_SELECTION,
-                TextClassifierEvent.TYPE_SELECTION_MODIFIED)
-                .setEventIndex(1)
-                .setEventTime(1000)
-                .setEntityType(TextClassifier.TYPE_DATE)
-                .setRelativeWordStartIndex(4)
-                .setRelativeWordEndIndex(3)
-                .setRelativeSuggestedWordStartIndex(2)
-                .setRelativeSuggestedWordEndIndex(1)
-                .setLanguage("de")
-                .setResultId("id")
-                .setActionIndices(3)
-                .setExtras(extra)
-                .setEventContext(new TextClassificationContext.Builder(
-                        InstrumentationRegistry.getTargetContext().getPackageName(),
-                        TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW)
-                        .setWidgetVersion("notification")
-                        .build())
-                .build();
-
-        final Parcel parcel = Parcel.obtain();
-        event.writeToParcel(parcel, event.describeContents());
-        parcel.setDataPosition(0);
-        final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
-
-        assertThat(result.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_SELECTION);
-        assertThat(result.getEventType()).isEqualTo(TextClassifierEvent.TYPE_SELECTION_MODIFIED);
-        assertThat(result.getEventIndex()).isEqualTo(1);
-        assertThat(result.getEventTime()).isEqualTo(1000);
-        assertThat(result.getEntityType()).isEqualTo(TextClassifier.TYPE_DATE);
-        assertThat(result.getRelativeWordStartIndex()).isEqualTo(4);
-        assertThat(result.getRelativeWordEndIndex()).isEqualTo(3);
-        assertThat(result.getRelativeSuggestedWordStartIndex()).isEqualTo(2);
-        assertThat(result.getRelativeSuggestedWordEndIndex()).isEqualTo(1);
-        assertThat(result.getLanguage()).isEqualTo("de");
-        assertThat(result.getResultId()).isEqualTo("id");
-        assertThat(result.getActionIndices()).asList().containsExactly(3);
-        assertThat(result.getExtras().get("k")).isEqualTo("v");
-        assertThat(result.getEventContext().getPackageName())
-                .isEqualTo(InstrumentationRegistry.getTargetContext().getPackageName());
-        assertThat(result.getEventContext().getWidgetType())
-                .isEqualTo(TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW);
-        assertThat(result.getEventContext().getWidgetVersion()).isEqualTo("notification");
+        assertThat(event.getEntityTypes()).isEmpty();
     }
 }
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
index 203be4d..6f82d6f 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
@@ -17,15 +17,12 @@
 package android.voiceinteraction.service;
 
 import android.app.VoiceInteractor;
-import android.app.VoiceInteractor.Prompt;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.LauncherApps;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.service.voice.VoiceInteractionSession;
-import android.service.voice.VoiceInteractionSession.ConfirmationRequest;
-import android.service.voice.VoiceInteractionSession.PickOptionRequest;
 import android.util.Log;
 import android.voiceinteraction.common.Utils;
 
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
index 4999fbe..b5d5938 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
@@ -17,9 +17,6 @@
 package android.voiceinteraction.cts;
 
 import android.app.Activity;
-import android.content.Intent;
-import android.content.ComponentName;
-import android.content.Context;
 import android.os.Bundle;
 import android.util.Log;
 import android.voiceinteraction.common.Utils;
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
index 1abd00f..732cff2 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
@@ -43,6 +43,7 @@
     private TestResultsReceiver mReceiver;
     private Bundle mResults;
     private final CountDownLatch mLatch = new CountDownLatch(1);
+    // TODO: convert test to JUnit4 so we can use @RequiredFeatureRule instead
     protected boolean mHasFeature;
     protected static final String FEATURE_VOICE_RECOGNIZERS = "android.software.voice_recognizers";
 
@@ -53,13 +54,14 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        startTestActivity();
+
         mContext = getInstrumentation().getTargetContext();
         mHasFeature = mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS);
-        if (mHasFeature) {
-            mReceiver = new TestResultsReceiver();
-            mContext.registerReceiver(mReceiver, new IntentFilter(Utils.BROADCAST_INTENT));
-        }
+        if (!mHasFeature) return;
+
+        mReceiver = new TestResultsReceiver();
+        mContext.registerReceiver(mReceiver, new IntentFilter(Utils.BROADCAST_INTENT));
+        startTestActivity();
     }
 
     @Override
@@ -87,12 +89,13 @@
     }
 
     public void testAll() throws Exception {
-        VoiceInteractionTestReceiver.waitSessionStarted(this, 5, TimeUnit.SECONDS);
-
         if (!mHasFeature) {
             Log.i(TAG, "The device doesn't support feature: " + FEATURE_VOICE_RECOGNIZERS);
             return;
         }
+
+        VoiceInteractionTestReceiver.waitSessionStarted(this, 5, TimeUnit.SECONDS);
+
         if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
             fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
             return;
@@ -116,7 +119,7 @@
     }
 
     private void verifySingleTestcaseResult(Utils.TestCaseType testCaseType, String result) {
-        Log.i(TAG, "Recevied testresult: " + result + " for " + testCaseType);
+        Log.i(TAG, "Received testresult: " + result + " for " + testCaseType);
         switch (testCaseType) {
           case ABORT_REQUEST_CANCEL_TEST:
               assertTrue(result.equals(Utils.ABORT_REQUEST_CANCEL_SUCCESS));
diff --git a/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
index 7c6cf53..11f330e 100644
--- a/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
+++ b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
@@ -26,11 +26,9 @@
 import android.app.VoiceInteractor.PickOptionRequest.Option;
 import android.app.VoiceInteractor.Prompt;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
-import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -134,10 +132,10 @@
     }
 
     private void broadcastResults() {
-        Intent intent = new Intent(Utils.BROADCAST_INTENT);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        intent.putExtras(mTotalInfo);
-        Log.i(TAG, "broadcasting: " + intent.toString() + ", Bundle = " + mTotalInfo.toString());
+        Intent intent = new Intent(Utils.BROADCAST_INTENT)
+            .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+            .putExtras(mTotalInfo);
+        Log.i(TAG, "broadcasting: " + intent + ", Bundle = " + mTotalInfo);
         sendOrderedBroadcast(intent, null, new DoneReceiver(),
                              null, Activity.RESULT_OK, null, null);
     }
diff --git a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
index ca61b24..5435cf8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
@@ -16,7 +16,7 @@
 package android.webkit.cts;
 
 import android.webkit.ConsoleMessage;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 
 // A chrome client for listening webview chrome events.
 class ChromeClient extends WaitForProgressClient {
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index fb646c9..e240978 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -35,8 +35,8 @@
 import android.webkit.WebResourceResponse;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 
 import com.android.compatibility.common.util.LocationUtils;
 import com.android.compatibility.common.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index 9b7a5bf..f4724cf 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -19,7 +19,7 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.webkit.HttpAuthHandler;
 import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 
diff --git a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
index cc1704b..2b9e8e5 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
@@ -25,7 +25,7 @@
 import android.webkit.WebResourceRequest;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
index 9bc0daa..32f2df0 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
@@ -20,7 +20,7 @@
 import android.webkit.TracingConfig;
 import android.webkit.TracingController;
 import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index b67322a..c881de4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -27,7 +27,7 @@
 import android.webkit.WebIconDatabase;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index 84a5efc..d2c54f0 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -19,7 +19,7 @@
 import android.graphics.Bitmap;
 import android.test.ActivityInstrumentationTestCase2;
 import android.webkit.WebBackForwardList;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 import android.webkit.WebHistoryItem;
 import android.webkit.WebIconDatabase;
 import android.webkit.WebView;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 542b66e..eac21a9 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -34,8 +34,8 @@
 import android.webkit.WebStorage;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 997f876..c29054a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -34,7 +34,7 @@
 import android.webkit.WebSettings;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
 import android.util.Pair;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index e6c79db..7fd8fc8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -29,7 +29,7 @@
 import android.webkit.WebSettings;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 import com.android.compatibility.common.util.PollingCheck;
@@ -727,12 +727,23 @@
         mOnUiThread.clearSslPreferences();
         mOnUiThread.loadUrlAndWaitForCompletion(url);
         // Page NOT loaded OK...
-        // In this case, we must NOT have received the onReceivedSslError callback as that is for
-        // recoverable (e.g. server auth) errors, whereas failing mandatory client auth is non-
-        // recoverable and should drop straight through to a load error.
-        assertFalse(webViewClient.wasOnReceivedSslErrorCalled());
-        assertFalse(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
-        assertEquals(WebViewClient.ERROR_FAILED_SSL_HANDSHAKE, webViewClient.onReceivedErrorCode());
+        //
+        // In this test, we expect both a recoverable and non-recoverable error:
+        //
+        //  1. WebView does not trust the test server's certificate. This is a recoverable error, so
+        //     WebView invokes #onReceivedSslError (and the WebViewClient calls #proceed). We don't
+        //     specifically intend to test this part of the scenario, but we can't easily mock out
+        //     WebView's certificate roots.
+        //  2. WebView proceeds with the handshake without providing client authentication. The
+        //     server fails the client. This is non-recoverable, so WebView invokes
+        //     #onReceivedError.
+        //
+        // We only assert the second error, since earlier WebView versions had a bug in which
+        // WebView hit error 2 first, which prevented it from hitting error 1.
+        assertFalse("Title should not be updated, since page load should have failed",
+                TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals("Expected ERROR_FAILED_SSL_HANDSHAKE in onReceivedError",
+                WebViewClient.ERROR_FAILED_SSL_HANDSHAKE, webViewClient.onReceivedErrorCode());
     }
 
     public void testProceedClientCertRequest() throws Throwable {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 6922d74..2f95f82 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -74,8 +74,8 @@
 import android.webkit.WebView.VisualStateCallback;
 import android.webkit.WebViewClient;
 import android.webkit.WebViewDatabase;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
 import android.widget.LinearLayout;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
@@ -954,7 +954,7 @@
         childOnUiThread.addJavascriptInterface(obj, "dummy");
 
         final SettableFuture<Void> onCreateWindowFuture = SettableFuture.create();
-        mOnUiThread.setWebChromeClient(new WebViewOnUiThread.WaitForProgressClient(mOnUiThread) {
+        mOnUiThread.setWebChromeClient(new WebViewSyncLoader.WaitForProgressClient(mOnUiThread) {
             @Override
             public boolean onCreateWindow(
                 WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
diff --git a/tests/tests/widget/res/layout/textview_isHorizontallyScrolling_layout.xml b/tests/tests/widget/res/layout/textview_isHorizontallyScrollable_layout.xml
similarity index 100%
rename from tests/tests/widget/res/layout/textview_isHorizontallyScrolling_layout.xml
rename to tests/tests/widget/res/layout/textview_isHorizontallyScrollable_layout.xml
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index 4384c0c..f083053 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -1428,7 +1428,8 @@
         final View anchor = mActivity.findViewById(R.id.anchor_middle);
         final LayoutParams anchorLayoutParams = anchor.getLayoutParams();
 
-        final int[] originalLocation = mPopupWindow.getContentView().getLocationOnScreen();
+        final int[] originalLocation = new int[2];
+        mPopupWindow.getContentView().getLocationOnScreen(originalLocation);
 
         final int deltaX = 30;
         final int deltaY = 20;
@@ -1562,8 +1563,10 @@
                 mPopupWindow.getContentView().findViewById(R.id.anchor_middle)));
         mInstrumentation.waitForIdleSync();
 
-        final int[] popupLocation = mPopupWindow.getContentView().getLocationOnScreen();
-        final int[] subPopupLocation = subPopup.getContentView().getLocationOnScreen();
+        final int[] popupLocation = new int[2];
+        mPopupWindow.getContentView().getLocationOnScreen(popupLocation);
+        final int[] subPopupLocation = new int[2];
+        subPopup.getContentView().getLocationOnScreen(subPopupLocation);
 
         final int deltaX = 20;
         final int deltaY = 30;
@@ -1579,11 +1582,13 @@
         // the anchor change), we need to wait until all traversals are done.
         mInstrumentation.waitForIdleSync();
 
-        final int[] newPopupLocation = mPopupWindow.getContentView().getLocationOnScreen();
+        final int[] newPopupLocation = new int[2];
+        mPopupWindow.getContentView().getLocationOnScreen(newPopupLocation);
         assertEquals(popupLocation[0] - deltaX, newPopupLocation[0]);
         assertEquals(popupLocation[1] - deltaY, newPopupLocation[1]);
 
-        final int[] newSubPopupLocation = subPopup.getContentView().getLocationOnScreen();
+        final int[] newSubPopupLocation = new int[2];
+        subPopup.getContentView().getLocationOnScreen(newSubPopupLocation);
         assertEquals(subPopupLocation[0] - deltaX, newSubPopupLocation[0]);
         assertEquals(subPopupLocation[1] - deltaY, newSubPopupLocation[1]);
     }
@@ -1598,7 +1603,8 @@
     }
 
     private void assertPopupLocation(int[] originalLocation, int deltaX, int deltaY) {
-        final int[] actualLocation = mPopupWindow.getContentView().getLocationOnScreen();
+        final int[] actualLocation = new int[2];
+        mPopupWindow.getContentView().getLocationOnScreen(actualLocation);
         assertEquals(originalLocation[0] - deltaX, actualLocation[0]);
         assertEquals(originalLocation[1] - deltaY, actualLocation[1]);
     }
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java b/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
similarity index 81%
rename from tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java
rename to tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
index f3e3847..4dd1bf7 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
@@ -33,18 +33,18 @@
 
 
 /**
- * Test {@link TextView#isHorizontallyScrolling}.
+ * Test {@link TextView#isHorizontallyScrollable}.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class TextViewIsHorizontallyScrollingTest {
+public class TextViewIsHorizontallyScrollableTest {
     private ViewGroup mViewGroup;
 
     @Before
     public void setup() {
         final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         final LayoutInflater inflater = LayoutInflater.from(context);
-        mViewGroup = (ViewGroup) inflater.inflate(R.layout.textview_isHorizontallyScrolling_layout,
+        mViewGroup = (ViewGroup) inflater.inflate(R.layout.textview_isHorizontallyScrollable_layout,
                 null);
     }
 
@@ -53,7 +53,7 @@
         final TextView textView = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_default);
 
-        assertFalse(textView.isHorizontallyScrolling());
+        assertFalse(textView.isHorizontallyScrollable());
     }
 
     @Test
@@ -62,7 +62,7 @@
                 R.id.textView_scrollHorizontally_default);
 
         textView.setHorizontallyScrolling(true);
-        assertTrue(textView.isHorizontallyScrolling());
+        assertTrue(textView.isHorizontallyScrollable());
     }
 
     @Test
@@ -70,10 +70,10 @@
         final TextView textView = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_default);
         textView.setHorizontallyScrolling(true);
-        assertTrue(textView.isHorizontallyScrolling());
+        assertTrue(textView.isHorizontallyScrollable());
 
         textView.setHorizontallyScrolling(false);
-        assertFalse(textView.isHorizontallyScrolling());
+        assertFalse(textView.isHorizontallyScrollable());
     }
 
     @Test
@@ -82,42 +82,42 @@
                 R.id.textView_scrollHorizontally_true);
         // It should return true here. But because of this bug b/120448952,
         // singleLine will overwrite scrollHorizontally.
-        assertFalse(textViewTrue.isHorizontallyScrolling());
+        assertFalse(textViewTrue.isHorizontallyScrollable());
 
         final TextView textViewFalse = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_false);
-        assertFalse(textViewFalse.isHorizontallyScrolling());
+        assertFalse(textViewFalse.isHorizontallyScrollable());
     }
 
     @Test
     public void testIsHorizontallyScrollingSetInXML_returnTrueWhenSingleLineIsTrue() {
         final TextView textViewDefault = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_default_singleLine_true);
-        assertTrue(textViewDefault.isHorizontallyScrolling());
+        assertTrue(textViewDefault.isHorizontallyScrollable());
 
         final TextView textViewTrue = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_true_singleLine_true);
-        assertTrue(textViewTrue.isHorizontallyScrolling());
+        assertTrue(textViewTrue.isHorizontallyScrollable());
 
         final TextView textViewFalse = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_false_singleLine_true);
-        assertTrue(textViewFalse.isHorizontallyScrolling());
+        assertTrue(textViewFalse.isHorizontallyScrollable());
     }
 
     @Test
     public void testIsHorizontallyScrollingSetInXML_returnGivenValueWhenSingleLineIsFalse() {
         final TextView textViewDefault = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_default_singleLine_false);
-        assertFalse(textViewDefault.isHorizontallyScrolling());
+        assertFalse(textViewDefault.isHorizontallyScrollable());
 
         final TextView textViewTrue = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_true_singleLine_false);
         // It should return true here. But because of this bug b/120448952,
         // singleLine will overwrite scrollHorizontally.
-        assertFalse(textViewTrue.isHorizontallyScrolling());
+        assertFalse(textViewTrue.isHorizontallyScrollable());
 
         final TextView textViewFalse = mViewGroup.findViewById(
                 R.id.textView_scrollHorizontally_false_singleLine_false);
-        assertFalse(textViewFalse.isHorizontallyScrolling());
+        assertFalse(textViewFalse.isHorizontallyScrollable());
     }
 }
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done
deleted file mode 100644
index da30626..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_add_double_2.java
-.class public dot.junit.opcodes.add_double.d.T_add_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
-       const v3, 3.1415
-       add-double v0, v3, v5
-       return-wide v5
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done
deleted file mode 100644
index 3633e01..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_add_double_2addr_2.java
-.class public dot.junit.opcodes.add_double_2addr.d.T_add_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
-       const v3, 3.1415
-       add-double/2addr v3, v5
-       return-wide v5
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done
deleted file mode 100644
index 9dab202..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_add_long_4.java
-.class public dot.junit.opcodes.add_long.d.T_add_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-
-       const v5, 12345.0
-       add-long v0, v3, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done
deleted file mode 100644
index 1073b6c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_add_long_2addr_4.java
-.class public dot.junit.opcodes.add_long_2addr.d.T_add_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-
-       const v5, 12345.0
-       add-long/2addr v3, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done
deleted file mode 100644
index 7c9185c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_and_long_2.java
-.class public dot.junit.opcodes.and_long.d.T_and_long_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
-       const v10, 3.1415
-       and-long v0, v10, v12
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done
deleted file mode 100644
index e1a4376..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_and_long_2addr_2.java
-.class public dot.junit.opcodes.and_long_2addr.d.T_and_long_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
-       const v0, 3.1415
-       and-long/2addr v0, v12
-       return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done
deleted file mode 100644
index 4b2642d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done
+++ /dev/null
@@ -1,132 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestStubs.java
-.interface abstract dot.junit.opcodes.aput_object.d.SuperInterface
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.aput_object.d.SuperInterface2
-    
-.source TestStubs.java    
-.class public dot.junit.opcodes.aput_object.d.SuperClass 
-.super java/lang/Object
-.implements dot.junit.opcodes.aput_object.d.SuperInterface
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-    
-.source TestStubs.java
-.class public dot.junit.opcodes.aput_object.d.SubClass 
-.super dot.junit.opcodes.aput_object.d.SuperClass
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, dot/junit/opcodes/aput_object/d/SuperClass/<init>()V
-       return-void
-.end method
-
-
-.source T_aput_object_3.java
-.class public dot.junit.opcodes.aput_object.d.T_aput_object_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 32
-
-    const v1, 0
-
-    const v0, 1
-    ; v2 = SubClass[]
-    new-array v2, v0, [Ldot/junit/opcodes/aput_object/d/SubClass;
-    
-    ; v3 =  SuperClass[]
-    new-array v3, v0, [Ldot/junit/opcodes/aput_object/d/SuperClass;
-
-    ; v4 =     SubClass
-    new-instance v4, dot/junit/opcodes/aput_object/d/SubClass
-    invoke-direct {v4}, dot/junit/opcodes/aput_object/d/SubClass/<init>()V
-
-    ; v5 =     SuperClass
-    new-instance v5, dot/junit/opcodes/aput_object/d/SuperClass
-    invoke-direct {v5}, dot/junit/opcodes/aput_object/d/SuperClass/<init>()V
-
-    ; v6 = SuperInterface[]
-    new-array v6, v0, [Ldot/junit/opcodes/aput_object/d/SuperInterface;
-
-    ; v7 =     Object[]
-    new-array v7, v0, [Ljava/lang/Object;
-    
-    ; v8 = SuperInterface2[]
-    new-array v8, v0, [Ldot/junit/opcodes/aput_object/d/SuperInterface2;
-    
-    const/4 v0, 0
-    
-; (SubClass -> SuperClass[])
-    aput-object v4, v3, v0
-    
-; (SubClass -> SuperInterface[])
-    aput-object v4, v6, v0
-    
-; (SubClass -> Object[])
-    aput-object v4, v7, v0
-        
-; !(SuperClass -> SubClass[])    
-Label10:        
-    aput-object v5, v2, v0
-Label11:    
-    goto Label2
-Label12:
-    add-int/lit8 v1, v1, 1
-    goto Label2
-        
-; !(SuperClass -> SuperInterface2[])    
-Label2:
-Label20:    
-    aput-object v5, v8, v0
-Label21:    
-    goto Label3
-Label22:
-    add-int/lit8 v1, v1, 1
-    goto Label3
-
-; !(SubClass[] -> SuperInterface[])    
-Label3:
-Label30:    
-    aput-object v2, v6, v0
-Label31:    
-    goto Label4
-Label32:    
-    add-int/lit8 v1, v1, 1
-    goto Label4
-
-Label4:
-    return v1
-    
-.catch java/lang/ArrayStoreException from Label10 to Label11 using Label12
-.catch java/lang/ArrayStoreException from Label20 to Label21 using Label22
-.catch java/lang/ArrayStoreException from Label30 to Label31 using Label32
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done
deleted file mode 100644
index b7472cc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done
+++ /dev/null
@@ -1,149 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperInterface
-
-.source TestStubs.java    
-.interface public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperInterface2
-
-.source TestStubs.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperClass 
-.super java/lang/Object
-.implements dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-    
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method    
-
-.source TestStubs.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2.SubClass 
-.super dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass/<init>()V
-       return-void
-.end method
-
-
-.source T_check_cast_2.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 20
-
-    const v1, 0
-    
-; (SubClass instanceof SuperClass)    
-    new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
-    
-; (SubClass[] instanceof SuperClass[])    
-    const v11, 1
-    new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-    check-cast v10, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass;
-
-    
-; (SubClass[] instanceof Object)    
-    new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-    check-cast v10, java/lang/Object
-    
-; (SubClass instanceof SuperInterface)    
-    new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V    
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-        
-
-; !(SuperClass instanceof SubClass)    
-Label1:
-    new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
-    invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass/<init>()V
-Label10:    
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-Label11:    
-    goto Label2
-Label12:
-    add-int/lit16 v1, v1, 1
-    goto Label2
-        
-; !(SubClass instanceof SuperInterface2)    
-Label2:
-    new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V    
-Label20:    
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface2
-Label21:    
-    goto Label3
-Label22:
-    add-int/lit16 v1, v1, 1
-    goto Label3
-
-; !(SubClass[] instanceof SuperInterface)    
-Label3:
-    new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label30:    
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-Label31:    
-    goto Label4
-Label32:    
-    add-int/lit16 v1, v1, 1
-    goto Label4
-
-; !(SubClass[] instanceof SubClass)    
-Label4:
-    new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label40:    
-    check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-Label41:    
-    goto Label5
-Label42:
-    add-int/lit16 v1, v1, 1
-    goto Label5    
-    
-; !(SuperClass[] instanceof SubClass[])    
-Label5:
-    new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass;
-Label50:    
-    check-cast v10, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label51:    
-    goto Label6
-Label52:
-    add-int/lit16 v1, v1, 1
-    
-Label6:        
-    return v1
-    
-.catch java/lang/ClassCastException from Label10 to Label11 using Label12
-.catch java/lang/ClassCastException from Label20 to Label21 using Label22
-.catch java/lang/ClassCastException from Label30 to Label31 using Label32
-.catch java/lang/ClassCastException from Label40 to Label41 using Label42
-.catch java/lang/ClassCastException from Label50 to Label51 using Label52
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done
deleted file mode 100644
index 3d25d6b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_cmp_long_3.java
-.class public dot.junit.opcodes.cmp_long.d.T_cmp_long_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)I
-.limit regs 14
-
-       const v10, 3.1415
-       cmp-long v0, v10, v12
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done
deleted file mode 100644
index 5704511..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_cmpg_double_2.java
-.class public dot.junit.opcodes.cmpg_double.d.T_cmpg_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)I
-.limit regs 16
-
-       const v14, 3.14
-       cmpg-double v0, v12, v14
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done
deleted file mode 100644
index 49566ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_cmpl_double_2.java
-.class public dot.junit.opcodes.cmpl_double.d.T_cmpl_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)I
-.limit regs 16
-
-       const v14, 3.14
-       cmpl-double v0, v12, v14
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done
deleted file mode 100644
index 6359d92..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_1.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
-       const-class v254, java/lang/String
-       return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done
deleted file mode 100644
index 50da342..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_3.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-class v3, java/lang/Object
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done
deleted file mode 100644
index 6f6b7b9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_4.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 3
-       const-wide v0, 1234    
-       const-class v1, java/lang/Object
-
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done
deleted file mode 100644
index 24186a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_5.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 255
-
-       const-class v254, java/lang/Object
-       return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done
deleted file mode 100644
index bd893c9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_6.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
-       const-class v254, java/lang/StringNNNNN
-       return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done
deleted file mode 100644
index 20d9749..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_class_7.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
-       const-class v254, dot/junit/opcodes/const_class/TestStubs
-       return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done
deleted file mode 100644
index b2ddede..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_wide_2.java
-.class public dot.junit.opcodes.const_wide.d.T_const_wide_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 255
-
-       const-wide v253, 20000000000
-       return-wide v253
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done
deleted file mode 100644
index c051462..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_wide_high16_1.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 255
-
-       const-wide/high16 v252, 0x1234000000000000
-       return-wide v252
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done
deleted file mode 100644
index 24a577c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_wide_high16_3.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide/high16 v3, 0x1234000000000000
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done
deleted file mode 100644
index 614e5a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_const_wide_high16_4.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 3
-       const-wide v0, 1234    
-       const-wide/high16 v1, 0x1234000000000000
-
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done
deleted file mode 100644
index e09176a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_div_double_2.java
-.class public dot.junit.opcodes.div_double.d.T_div_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 14
-
-       const v10, 3.1415
-       div-double v0, v10, v12
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done
deleted file mode 100644
index 5921ceb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_div_double_2addr_2.java
-.class public dot.junit.opcodes.div_double_2addr.d.T_div_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 14
-
-       const v0, 3.1415
-       div-double/2addr v0, v12
-       return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done
deleted file mode 100644
index 409b45a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_div_long_4.java
-.class public dot.junit.opcodes.div_long.d.T_div_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
-       const v10, 3.14
-       div-long v0, v10, v12
-       return-wide v12
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done
deleted file mode 100644
index 6d91919..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_div_long_2addr_4.java
-.class public dot.junit.opcodes.div_long_2addr.d.T_div_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
-       const v0, 3.14
-       div-long/2addr v0, v12
-       return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done
deleted file mode 100644
index 402cfac..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_double_to_float_2.java
-.class public dot.junit.opcodes.double_to_float.d.T_double_to_float_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)F
-.limit regs 8
-
-       const v6, 3.14
-       double-to-float v0, v6
-       return v6
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done
deleted file mode 100644
index 135e7ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_double_to_float_4.java
-.class public dot.junit.opcodes.double_to_float.d.T_double_to_float_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)F
-.limit regs 8
-
-       double-to-float v0, v5
-       
-       const v3, 3.14
-       return v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done
deleted file mode 100644
index 7e3a98b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_double_to_int_2.java
-.class public dot.junit.opcodes.double_to_int.d.T_double_to_int_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)I
-.limit regs 8
-
-       const v6, 3.14
-       double-to-int v0, v6
-       const v1, 123
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done
deleted file mode 100644
index 54740b6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_double_to_long_2.java
-.class public dot.junit.opcodes.double_to_long.d.T_double_to_long_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)J
-.limit regs 8
-
-       const v6, 3.14
-       double-to-long v0, v6
-       const-wide v2, 123
-       return-wide v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done
deleted file mode 100644
index 1c97601..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_1.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done
deleted file mode 100644
index b462d1c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_11.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done
deleted file mode 100644
index c3ce952..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done
+++ /dev/null
@@ -1,43 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_12.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    goto Label0
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    return-void
-Label0:    
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done
deleted file mode 100644
index 0066d29..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_13.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done
deleted file mode 100644
index 6167ef7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_2.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([D)V
-.limit regs 10
-
-    fill-array-data v9 D
-        1.0
-        2.0
-        3.0
-        4.0
-        5.0
-    fill-array-data-end
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done
deleted file mode 100644
index e6ecd1e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_3.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v10 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done
deleted file mode 100644
index 221ef8b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_4.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D[I)V
-.limit regs 10
-    
-    fill-array-data v7 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done
deleted file mode 100644
index cc98351..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_5.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(J[I)V
-.limit regs 10
-    
-    fill-array-data v7 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done
deleted file mode 100644
index 61990a1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_6.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v8 I
-        0
-        0
-        0
-        0
-        0
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done
deleted file mode 100644
index 8ba5155..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_7.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([Ljava/lang/Object;)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        0
-        0
-        0
-        0
-        0
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done
deleted file mode 100644
index e90eb86..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_8.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([D)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done
deleted file mode 100644
index 0a5e008..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_fill_array_data_9.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-    
-    fill-array-data v9 I
-        1
-        2
-        3
-        4
-        5
-    fill-array-data-end
-    
-    
-    return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done
deleted file mode 100644
index 32f2b0a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_float_to_double_4.java
-.class public dot.junit.opcodes.float_to_double.d.T_float_to_double_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()D
-.limit regs 1
-
-       const v0, 3.14
-       float-to-double v0, v0
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done
deleted file mode 100644
index 69d1e57..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_float_to_long_4.java
-.class public dot.junit.opcodes.float_to_long.d.T_float_to_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 1
-
-       const v0, 3.14
-       float-to-long v0, v0
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done
deleted file mode 100644
index caa4ad0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_16_1.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-; test positive offset
-      goto/16 Label2
-LabelReturn:      
-      return v4
-      
-Label2:
-       add-int/lit8 v4, v4, -1
-       if-lez v4, LabelExit
-; test negative offset       
-       goto/16 Label2
-       
-LabelExit:       
-       goto LabelReturn
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done
deleted file mode 100644
index 7162694..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_16_2.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-      goto/16 Label2
-Label2:
-       return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done
deleted file mode 100644
index fcaa68d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_16_3.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-      goto/16 Label2
-Label2:
-       return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done
deleted file mode 100644
index 746c325..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_16_4.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-      goto/16 Label1
-Label1:      
-      return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done
deleted file mode 100644
index fd5335a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_32_1.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-; test positive offset
-      goto/32 Label2
-LabelReturn:      
-      return v4
-      
-Label2:
-       add-int/lit8 v4, v4, -1
-       if-lez v4, LabelExit
-; test negative offset       
-       goto/32 Label2
-       
-LabelExit:       
-       goto LabelReturn
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done
deleted file mode 100644
index 1a76901..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_32_2.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-      goto/32 Label2
-Label2:
-       return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done
deleted file mode 100644
index 6130ae8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_32_3.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-      goto/32 Label2
-Label2:
-       return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done
deleted file mode 100644
index 624dfaf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_goto_32_4.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-Label1:
-      goto/32 Label1
-      return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done
deleted file mode 100644
index faa6271..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_14.java
-.class public dot.junit.opcodes.iget.d.T_iget_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget v0, v2, dot.junit.opcodes.iget.d.T_iget_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done
deleted file mode 100644
index bf07640..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_2.java
-.class public dot.junit.opcodes.iget.d.T_iget_2
-.super java/lang/Object
-
-.field public  val F
-
-.method  <clinit>()V
-.limit regs 2
-       return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       
-       const v0, 123.0
-       iput v0, v1, dot.junit.opcodes.iget.d.T_iget_2.val F
-       
-       return-void
-.end method
-
-.method public run()F
-.limit regs 4
-
-       iget v1, v3, dot.junit.opcodes.iget.d.T_iget_2.val F
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done
deleted file mode 100644
index 38a56f6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_boolean_14.java
-.class public dot.junit.opcodes.iget_boolean.d.T_iget_boolean_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-boolean v0, v2, dot.junit.opcodes.iget_boolean.d.T_iget_boolean_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done
deleted file mode 100644
index f33ce5d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_byte_14.java
-.class public dot.junit.opcodes.iget_byte.d.T_iget_byte_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-byte v0, v2, dot.junit.opcodes.iget_byte.d.T_iget_byte_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done
deleted file mode 100644
index 46f0e20..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_char_14.java
-.class public dot.junit.opcodes.iget_char.d.T_iget_char_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-char v0, v2, dot.junit.opcodes.iget_char.d.T_iget_char_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done
deleted file mode 100644
index 5e4967f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_1.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_1
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-.field protected  p1 Ljava/lang/Object;
-.field private  pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       
-       const v0, 0
-       iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.i1 Ljava/lang/Object;
-
-       const v0, 0
-       iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.p1 Ljava/lang/Object;
-
-       const v0, 0
-       iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.pvt1 Ljava/lang/Object;
-       
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_1.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done
deleted file mode 100644
index 10143a7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_21.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_21
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       
-       new-instance v0, java/lang/Object
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       
-       iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_21.i1 Ljava/lang/Object;
-       
-       return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 3
-
-       iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_21.i1 Ljava/lang/String;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done
deleted file mode 100644
index 4999f1a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_3.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_3
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-object v3, v2, dot.junit.opcodes.iget_object.d.T_iget_object_3.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done
deleted file mode 100644
index 621f235..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_30.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_30
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-    new-instance v0, dot/junit/opcodes/iget_object/d/T_iget_object_30
-    iget-object v1, v0, dot.junit.opcodes.iget_object.d.T_iget_object_30.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done
deleted file mode 100644
index f194ecd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2014 The Android Open Source Project
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-;      http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-; See the License for the specific language governing permissions and
-; limitations under the License.
-
-.source T_iget_object_31.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_31
-.super java/lang/Object
-
-.field public st_i1 Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
-.limit regs 3
-    iget v0, v0, dot.junit.opcodes.iget_object.d.T_iget_object_31.st_i1 Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
-    return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done
deleted file mode 100644
index 9a05156..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_4.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_4
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_4.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done
deleted file mode 100644
index ed15e90..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_5.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_5
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 4
-
-       invoke-direct {v3}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_5.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done
deleted file mode 100644
index 7899b37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_object_9.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_9
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       const v0, 0
-       iget-object v1, v0, dot.junit.opcodes.iget_object.d.T_iget_object_9.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done
deleted file mode 100644
index 9e0367a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_short_14.java
-.class public dot.junit.opcodes.iget_short.d.T_iget_short_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-short v0, v2, dot.junit.opcodes.iget_short.d.T_iget_short_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done
deleted file mode 100644
index 3919e04..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_wide_1.java
-.class public dot.junit.opcodes.iget_wide.d.T_iget_wide_1
-.super java/lang/Object
-
-.field public  i1 J
-.field protected  p1 J
-.field private  pvt1 J
-
-
-.method public <init>()V
-.limit regs 3
-
-       invoke-direct {v2}, java/lang/Object/<init>()V
-       
-       const-wide v0, 12345679890123
-       iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.i1 J
-
-       const-wide v0, 10
-       iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.p1 J
-
-       const-wide v0, 20
-       iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.pvt1 J
-       
-       return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
-       iget-wide v1, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.i1 J
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done
deleted file mode 100644
index 3ffdc18..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iget_wide_14.java
-.class public dot.junit.opcodes.iget_wide.d.T_iget_wide_14
-.super java/lang/Object
-
-.field public  i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iget-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done
deleted file mode 100644
index 4741d35..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_1.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(Ljava/lang/Object;)Z
-.limit regs 5
-
-       instance-of v0, v4, java/lang/String
-       return v0
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done
deleted file mode 100644
index 1299b54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done
+++ /dev/null
@@ -1,119 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperInterface
-
-.source TestStubs.java    
-.interface public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperInterface2
-
-.source TestStubs.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperClass 
-.super java/lang/Object
-.implements dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
-    
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method    
-
-.source TestStubs.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2.SubClass 
-.super dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass/<init>()V
-       return-void
-.end method
-
-
-.source T_instance_of_2.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Z
-.limit regs 20
-
-    const v0, 0
-    
-; (SubClass instanceof SuperClass)    
-    new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
-    if-eqz v15, LabelExit
-    
-; (SubClass[] instanceof SuperClass[])    
-    const v11, 1
-    new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
-    instance-of v15, v10, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass;
-    if-eqz v15, LabelExit
-
-; (SubClass[] instanceof Object)    
-    new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
-    instance-of v15, v10, java/lang/Object
-    if-eqz v15, LabelExit
-    
-; (SubClass instanceof SuperInterface)    
-    new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V    
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
-    if-eqz v15, LabelExit
-
-; !(SuperClass instanceof SubClass)    
-    new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
-    invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass/<init>()V
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
-    if-nez v15, LabelExit
-        
-; !(SubClass instanceof SuperInterface2)    
-    new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
-    invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V    
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface2
-    if-nez v15, LabelExit
-
-; !(SubClass[] instanceof SuperInterface)    
-    new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
-    if-nez v15, LabelExit
-
-; !(SubClass[] instanceof SubClass)    
-    new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
-    instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
-    if-nez v15, LabelExit
-    
-; !(SuperClass[] instanceof SubClass[])    
-    new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass;
-    instance-of v15, v10, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
-    if-nez v15, LabelExit
-    
-    const v0, 1
-    
-LabelExit:        
-    return v0
-    
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done
deleted file mode 100644
index 6705dcf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_3.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 6
-       instance-of v0, v5, dot/junit/opcodes/instance_of/TestStubs
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done
deleted file mode 100644
index fe8b891..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_4.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
-
-       instance-of v0, v4, java/lang/String
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done
deleted file mode 100644
index eac21b9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_5.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
-       const v3, 1234
-       instance-of v1, v3, java/lang/String
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done
deleted file mode 100644
index 4c2e649..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_6.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
-
-       instance-of v0, v5, java/lang/String
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done
deleted file mode 100644
index f0823e7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_instance_of_7.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
-       instance-of v0, v5, dot/junit/opcodes/instance_of/Test_instance_ofN
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done
deleted file mode 100644
index 8d872ad..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_25.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_25
-.super dot/junit/opcodes/invoke_direct/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_direct/TSuper/<init>()V
-       return-void
-.end method
-
-.method private test()V
-    return-void
-.end method
-
-.method public run()I
-.limit regs 6
-
-       new-instance v2, dot/junit/opcodes/invoke_direct/TPlain
-       invoke-direct {v2}, dot/junit/opcodes/invoke_direct/TPlain/<init>()V
-
-       invoke-direct {v2}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25/test()V
-       move-result v0
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done
deleted file mode 100644
index 40cce50..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_direct.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_direct.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_direct.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_direct_26.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_26
-.super dot/junit/opcodes/invoke_direct/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_direct/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-direct {v7}, dot/junit/opcodes/invoke_direct/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done
deleted file mode 100644
index 0ac6b37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done
+++ /dev/null
@@ -1,41 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_27.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_27
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test()V
-    return-void
-.end method
-
-.method public static run()V
-.limit regs 3
-
-       new-instance v0, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27
-       
-       invoke-direct {v0}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27/test()V
-       
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done
deleted file mode 100644
index ed919f9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_4.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_4
-.super java/lang/Object
-
-.method static <clinit>()V
-    return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-    invoke-direct {}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4/<clinit>()V
-    return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done
deleted file mode 100644
index 262b5ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_9.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
-       invoke-direct {v2}, dot.junit.opcodes.invoke_direct.d.T_invoke_direct_9/toInt()I
-
-       move-result v0
-       return v0
-.end method
-
-
-.method private native toInt()I
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done
deleted file mode 100644
index 31a24c4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_range_24.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_24
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test(II)I
-.limit regs 7
-       const v0, 999
-       const v1, 888
-       const v2, 777
-       
-       div-int v4, v5, v6
-       
-       return v4
-.end method
-
-.method public run()I
-.limit regs 7
-       const v0, 111
-       const v1, 222
-       const v2, 333
-       
-       
-       const-wide v4, 50
-          move-object v3, v6
-       invoke-direct {v3..v5}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24/test(II)I
-       move-result v3
-       
-       const v4, 2
-       if-ne v3, v4, Label30
-       
-       const v4, 111
-       if-ne v0, v4, Label30
-       
-       const v4, 222
-       if-ne v1, v4, Label30
-       
-       const v4, 333
-       if-ne v2, v4, Label30
-
-       const v0, 1       
-       return v0
-Label30:
-        const v0, 0
-        return v0
-        
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done
deleted file mode 100644
index 6c2334e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_range_25.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_25
-.super dot/junit/opcodes/invoke_direct_range/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_direct_range/TSuper/<init>()V
-       return-void
-.end method
-
-.method private test()V
-    return-void
-.end method
-
-.method public run()I
-.limit regs 6
-
-       new-instance v2, dot/junit/opcodes/invoke_direct_range/TPlain
-       invoke-direct {v2}, dot/junit/opcodes/invoke_direct_range/TPlain/<init>()V
-
-       invoke-direct/range {v2}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25/test()V
-       move-result v0
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done
deleted file mode 100644
index 6160fe5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_direct_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_direct_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_direct_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_direct_range_26.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_26
-.super dot/junit/opcodes/invoke_direct_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_direct_range/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-direct/range {v7}, dot/junit/opcodes/invoke_direct_range/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done
deleted file mode 100644
index 1073241..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done
+++ /dev/null
@@ -1,41 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_range_27.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_27
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test()V
-    return-void
-.end method
-
-.method public static run()V
-.limit regs 3
-
-       new-instance v0, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27
-       
-       invoke-direct/range {v0}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27/test()V
-       
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done
deleted file mode 100644
index a7aeae9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_range_4.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_4
-.super java/lang/Object
-
-.method static <clinit>()V
-    return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-    invoke-direct/range {v0}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4/<clinit>()V
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done
deleted file mode 100644
index 567bd84..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_direct_range_9.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
-       invoke-direct/range {v2}, dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_9/toInt()I
-
-       move-result v0
-       return v0
-.end method
-
-
-.method private native toInt()I
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done
deleted file mode 100644
index 6709286..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_interface_23.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_23
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done
deleted file mode 100644
index 577510a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_interface_24.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault2/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done
deleted file mode 100644
index 19b57b4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_interface_25.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_25
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done
deleted file mode 100644
index a8de67b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_interface_4.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-interface {v7}, dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4/test()V
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done
deleted file mode 100644
index 9314daa..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_interface_range_23.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_23
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done
deleted file mode 100644
index c70dfb6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_interface_range_24.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault2/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done
deleted file mode 100644
index fd10395..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_interface_range_25.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_25
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done
deleted file mode 100644
index 8a21324..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_interface_range_4.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-interface/range {v7}, dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4/test()V
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done
deleted file mode 100644
index 2e78a06..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_static_13.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-
-       invoke-static {v1}, dot/junit/opcodes/invoke_static/TestClass/test1(F)I
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done
deleted file mode 100644
index ed833e2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestClassInitError.java
-.class public dot.junit.opcodes.invoke_static.d.TestClassInitError
-.super java/lang/Object
-
-.method static public <clinit>()V
-.limit regs 2
-
-    const v0, 1
-    const v1, 0
-    div-int v0, v0, v1
-    return-void
-.end method
-
-.method static public test()V
-    return-void
-.end method
-
-.source T_invoke_static_14.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-
-       invoke-static {}, dot/junit/opcodes/invoke_static/d/TestClassInitError/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done
deleted file mode 100644
index 7332bce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestProtected.java
-.class public dot.junit.opcodes.invoke_static.d.TestProtected
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method protected static testP()I
-.limit regs 2
-    const v0, 888
-    return v0
-.end method
-
-
-.source T_invoke_static_18.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_18
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
-       invoke-static {}, dot/junit/opcodes/invoke_static/d/TestProtected/testP()I
-       move-result v0
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done
deleted file mode 100644
index 9a2871f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_static.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_static.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_static.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_static_24.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_24
-.super dot/junit/opcodes/invoke_static/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_static/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-static {v7}, dot/junit/opcodes/invoke_static/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done
deleted file mode 100644
index 969e499..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_static_6.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static native test()V
-.end method
-
-.method public run()V
-.limit regs 1
-
-       invoke-static {}, dot/junit/opcodes/invoke_static/d/T_invoke_static_6/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done
deleted file mode 100644
index dca327b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_static_range_13.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-
-       invoke-static/range {v1}, dot/junit/opcodes/invoke_static_range/TestClass/test1(F)I
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done
deleted file mode 100644
index 08c04ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestClassInitError.java
-.class public dot.junit.opcodes.invoke_static_range.d.TestClassInitError
-.super java/lang/Object
-
-.method static public <clinit>()V
-.limit regs 2
-
-    const v0, 1
-    const v1, 0
-    div-int v0, v0, v1
-    return-void
-.end method
-
-.method static public test()V
-    return-void
-.end method
-
-.source T_invoke_static_range_14.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-
-       invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/TestClassInitError/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done
deleted file mode 100644
index 19fec09..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestProtected.java
-.class public dot.junit.opcodes.invoke_static_range.d.TestProtected
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method protected static testP()I
-.limit regs 2
-    const v0, 888
-    return v0
-.end method
-
-
-.source T_invoke_static_range_18.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_18
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
-       invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/TestProtected/testP()I
-       move-result v0
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done
deleted file mode 100644
index 6ee8671..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_static_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_static_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_static_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_static_range_24.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_24
-.super dot/junit/opcodes/invoke_static_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_static_range/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-static/range {v7}, dot/junit/opcodes/invoke_static_range/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done
deleted file mode 100644
index a739336..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_static_range_6.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static native test()V
-.end method
-
-.method public run()V
-.limit regs 1
-
-       invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done
deleted file mode 100644
index 2e4f13f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_super.d.TSuper
-.super  java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public toInt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-    
-.method public toInt(F)I 
-.limit regs 3
-    float-to-int v0, v2
-    return v0
-.end method
-
-.method public native toIntNative()I    
-.end method
-    
-.method public static toIntStatic()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-  
-.method protected toIntP()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-
-.method private toIntPvt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-    
-.method public testArgsOrder(II)I
-.limit regs 4
-    const v0, 349
-    const v1, 344656
-    div-int v2, v2, v3
-    return v2
-.end method   
-
-.method public testString(Ljava/lang/String;)V
-.limit regs 2
-    return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done
deleted file mode 100644
index 55303d3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_super.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_super.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_super_24.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_24
-.super dot/junit/opcodes/invoke_super/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_super/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-super {v7}, dot/junit/opcodes/invoke_super/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done
deleted file mode 100644
index 1e68d5f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_super_26.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault/testDefault()V
-       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault2/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done
deleted file mode 100644
index 8bda6a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_super_27.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestNonDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done
deleted file mode 100644
index 350fdb8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestConflict.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestConflict
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.source T_invoke_super_28.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestConflict
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestConflict/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done
deleted file mode 100644
index 88def8a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_super_range.d.TSuper
-.super  java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public toInt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-    
-.method public toInt(F)I 
-.limit regs 3
-    float-to-int v0, v2
-    return v0
-.end method
-
-.method public native toIntNative()I    
-.end method
-    
-.method public static toIntStatic()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-  
-.method protected toIntP()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-
-.method private toIntPvt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-    
-.method public testArgsOrder(II)I
-.limit regs 4
-    const v0, 349
-    const v1, 344656
-    div-int v2, v2, v3
-    return v2
-.end method   
-
-.method public testString(Ljava/lang/String;)V
-.limit regs 2
-    return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done
deleted file mode 100644
index d30cc05..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_super_range_19.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_19
-.super dot/junit/opcodes/invoke_super_range/d/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_super_range/d/TSuper/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 4
-
-       move-object v0, v3
-       const/4 v1, 1
-       invoke-super/range {v0, v1}, dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19/toInt(I)I
-       move-result v0
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done
deleted file mode 100644
index dcc399d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_super_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_super_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-; =====================================
-
-.source T_invoke_super_range_24.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_24
-.super dot/junit/opcodes/invoke_super_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, dot/junit/opcodes/invoke_super_range/d/TTestInterfaceImpl/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       invoke-super/range {v7}, dot/junit/opcodes/invoke_super_range/d/TTestInterface/test()V
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done
deleted file mode 100644
index 8e53186..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_super_range_26.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault/testDefault()V
-       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault2/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done
deleted file mode 100644
index 752182c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_super_range_27.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestNonDefault/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done
deleted file mode 100644
index df29d4d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestConflict.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestConflict
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.source T_invoke_super_range_28.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestConflict
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestConflict/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done
deleted file mode 100644
index 1df3ae2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done
+++ /dev/null
@@ -1,67 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_virtual.d.TSuper
-.super  java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-
-
-.method public toInt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-    
-.method public toInt(F)I 
-.limit regs 3
-    float-to-int v0, v2
-    return v0
-.end method
-
-.method public native toIntNative()I    
-.end method
-    
-.method public static toIntStatic()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-  
-.method protected toIntP()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-
-.method private toIntPvt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-    
-.method public testArgsOrder(II)I
-.limit regs 4
-    const v0, 349
-    const v1, 344656
-    div-int v2, v2, v3
-    return v2
-.end method   
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done
deleted file mode 100644
index 1804cce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_virtual.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-.source T_invoke_virtual_24.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.TTestInterface
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       invoke-virtual {v3}, dot/junit/opcodes/invoke_virtual/d/TTestInterface/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done
deleted file mode 100644
index 0e87969..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_virtual_26.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done
deleted file mode 100644
index d34045b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_virtual_27.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done
deleted file mode 100644
index 8d3cf9e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_virtual_28.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done
deleted file mode 100644
index 5de2f49..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_virtual_4.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-       invoke-virtual {v2}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4/test()V
-       return-void
-.end method
-
-.method public native test()V
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done
deleted file mode 100644
index b375fc5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done
+++ /dev/null
@@ -1,67 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.TSuper
-.super  java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-
-
-.method public toInt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-    
-.method public toInt(F)I 
-.limit regs 3
-    float-to-int v0, v2
-    return v0
-.end method
-
-.method public native toIntNative()I    
-.end method
-    
-.method public static toIntStatic()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method
-  
-.method protected toIntP()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-
-.method private toIntPvt()I 
-.limit regs 3
-    const v0, 5
-    return v0
-.end method  
-    
-.method public testArgsOrder(II)I
-.limit regs 4
-    const v0, 349
-    const v1, 344656
-    div-int v2, v2, v3
-    return v2
-.end method   
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done
deleted file mode 100644
index 9e2022f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-.source T_invoke_virtual_range_24.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.TTestInterface
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public test()V
-    return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       invoke-virtual/range {v3}, dot/junit/opcodes/invoke_virtual_range/d/TTestInterface/test()V
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done
deleted file mode 100644
index 1d39236..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_virtual_range_25.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_25
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
-       new-instance v6, java/lang/Object
-       invoke-virtual/range {v6, v7}, java/lang/Object/equals(Ljava/lang/Object;)Z
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done
deleted file mode 100644
index 31ea1ee..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_virtual_range_26.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done
deleted file mode 100644
index ce470e3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_virtual_range_27.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done
deleted file mode 100644
index 5617cbd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2016 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
-    return-void
-.end method
-
-.source T_invoke_virtual_range_28.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 1
-       invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28/testDefault()V
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done
deleted file mode 100644
index f68a194..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_invoke_virtual_range_4.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-       invoke-direct {v1}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-       invoke-virtual/range {v2}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4/test()V
-       return-void
-.end method
-
-.method public native test()V
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done
deleted file mode 100644
index f7f8997..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_19.java
-.class public dot.junit.opcodes.iput.d.T_iput_19
-.super java/lang/Object
-
-.field public  st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-       iput v1, v2, dot.junit.opcodes.iput.d.T_iput_19.st_f1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done
deleted file mode 100644
index 0161449..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_20.java
-.class public dot.junit.opcodes.iput.d.T_iput_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const v0, 0
-       iput v0, v3, dot.junit.opcodes.iput.d.T_iput_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done
deleted file mode 100644
index aed12db..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_boolean_19.java
-.class public dot.junit.opcodes.iput_boolean.d.T_iput_boolean_19
-.super java/lang/Object
-
-.field public  st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-       iput-boolean v1, v2, dot.junit.opcodes.iput_boolean.d.T_iput_boolean_19.st_f1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done
deleted file mode 100644
index b7bb68c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_boolean_20.java
-.class public dot.junit.opcodes.iput_boolean.d.T_iput_boolean_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const v0, 0    
-       iput-boolean v0, v3, dot.junit.opcodes.iput_boolean.d.T_iput_boolean_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done
deleted file mode 100644
index 2452e5e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_byte_20.java
-.class public dot.junit.opcodes.iput_byte.d.T_iput_byte_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       iput-byte v3, v3, dot.junit.opcodes.iput_byte.d.T_iput_byte_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done
deleted file mode 100644
index 5aa31b2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_char_20.java
-.class public dot.junit.opcodes.iput_char.d.T_iput_char_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       iput-char v3, v3, dot.junit.opcodes.iput_char.d.T_iput_char_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done
deleted file mode 100644
index 6a9215e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_1.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_1
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-.field protected  st_p1 Ljava/lang/Object;
-.field private  st_pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public  getPvtField()Ljava/lang/Object;
-.limit regs 2
-
-       iget-object v0, v1, dot.junit.opcodes.iput_object.d.T_iput_object_1.st_pvt1 Ljava/lang/Object;
-       return-object v0
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_1.st_i1 Ljava/lang/Object;
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done
deleted file mode 100644
index 92f9cff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_10.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_10
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_10.st_i1N Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done
deleted file mode 100644
index 69f1309..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_12.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_12
-.super java/lang/Object
-
-.field public  final st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_12.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done
deleted file mode 100644
index f282745..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_13.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_13
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v0, 0
-       iput-object v2, v0, dot.junit.opcodes.iput_object.d.T_iput_object_13.st_i1 Ljava/lang/Object;
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done
deleted file mode 100644
index 805388f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_2.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_2
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v0, 1234    
-       iput-object v0, v2, dot.junit.opcodes.iput_object.d.T_iput_object_2.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done
deleted file mode 100644
index a9b90be..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_20.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/String;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       iput-object v3, v3, dot.junit.opcodes.iput_object.d.T_iput_object_20.st_o Ljava/lang/String;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done
deleted file mode 100644
index fa05a78..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_3.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_3
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-        iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_3.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done
deleted file mode 100644
index ace5b2c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_30.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_30
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-    new-instance v0, dot/junit/opcodes/iput_object/d/T_iput_object_30
-    const v1, 0
-    iput-object v1, v0, dot.junit.opcodes.iput_object.d.T_iput_object_30.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done
deleted file mode 100644
index 7b1b507..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2014 The Android Open Source Project
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-;      http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-; See the License for the specific language governing permissions and
-; limitations under the License.
-
-.source T_iput_object_31.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_31
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-    const v1, 0
-    iput-object v1, v0, dot.junit.opcodes.iput_object.d.T_iput_object_31.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done
deleted file mode 100644
index 8906abe..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_4.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_4
-.super java/lang/Object
-
-.field public  st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v3, v2, dot.junit.opcodes.iput_object.d.T_iput_object_4.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done
deleted file mode 100644
index 25768ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_7.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_7
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_7.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done
deleted file mode 100644
index 3fd712b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_object_9.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_9
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_9noclass.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done
deleted file mode 100644
index b7524dc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_short_20.java
-.class public dot.junit.opcodes.iput_short.d.T_iput_short_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       iput-short v3, v3, dot.junit.opcodes.iput_short.d.T_iput_short_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done
deleted file mode 100644
index cae692f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_wide_1.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_1
-.super java/lang/Object
-
-.field public  st_i1 J
-.field protected  st_p1 J
-.field private  st_pvt1 J
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public  getPvtField()J
-.limit regs 3
-
-       iget-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_1.st_pvt1 J
-       return-wide v0
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v0, 778899112233
-       iput-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_1.st_i1 J
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done
deleted file mode 100644
index cdf7fe6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_wide_13.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_13
-.super java/lang/Object
-
-.field public  st_i1 J
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v2, 0
-       const-wide v0, 778899112233
-       iput-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_13.st_i1 J
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done
deleted file mode 100644
index 1818bed..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_wide_18.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_18
-.super java/lang/Object
-
-.field public  st_i1 F
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1.0
-       iput-wide v1, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_18.st_i1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done
deleted file mode 100644
index e0efb25..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_iput_wide_20.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_20
-.super java/lang/Object
-
-.field public  st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const-wide v0, 0
-
-       iput-wide v0, v3, dot.junit.opcodes.iput_wide.d.T_iput_wide_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done
deleted file mode 100644
index 3201a77..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_long_to_double_2.java
-.class public dot.junit.opcodes.long_to_double.d.T_long_to_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(J)D
-.limit regs 8
-
-       const v6, 3.1415
-       long-to-double v0, v6
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done
deleted file mode 100644
index 1d4665b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_long_to_int_3.java
-.class public dot.junit.opcodes.long_to_int.d.T_long_to_int_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(J)I
-.limit regs 8
-
-       const v6, 1234.0
-       long-to-int v0, v6
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done
deleted file mode 100644
index 754a9e3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_monitor_enter_6.java
-.class public dot.junit.opcodes.monitor_enter.d.T_monitor_enter_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
-       const v5, 1.23
-       monitor-enter v5
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done
deleted file mode 100644
index 8fb7791..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_monitor_enter_7.java
-.class public dot.junit.opcodes.monitor_enter.d.T_monitor_enter_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
-       const-wide v4, 123456789321
-       monitor-enter v4
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done
deleted file mode 100644
index 9635212..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_monitor_exit_6.java
-.class public dot.junit.opcodes.monitor_exit.d.T_monitor_exit_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       monitor-enter v3
-       const v3, 1.123
-       monitor-exit v3
-       return-void       
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done
deleted file mode 100644
index c65ae56..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_monitor_exit_7.java
-.class public dot.junit.opcodes.monitor_exit.d.T_monitor_exit_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       monitor-enter v3
-       const-wide v0, 123456789321
-       monitor-exit v0
-       return-void       
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done
deleted file mode 100644
index bb5335f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_16_1.java
-.class public dot.junit.opcodes.move_16.d.T_move_16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
-       const v0, 123
-       const v1, 5678
-       
-       move/16 v4000, v0
-       move/16 v4001, v1
-       
-       move/16 v4000, v4001
-       
-       const/4 v4, 5678
-       
-       move/16 v0, v4000
-       move/16 v1, v4001
-
-       if-ne v0, v4, Label0
-       if-ne v1, v4, Label0
-       
-       const v1, 1
-       return v1
-
-Label0:
-       const v1, 0
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done
deleted file mode 100644
index 52454ae..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_16_2.java
-.class public dot.junit.opcodes.move_16.d.T_move_16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
-       const v1, 5678
-       
-       move/16 v4001, v1
-       move/16 v0, v4001
-       
-       const/4 v4, 5678
-
-       if-ne v0, v4, Label0
-       if-ne v1, v4, Label0
-       
-       const v1, 1
-       return v1
-
-Label0:
-       const v1, 0
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done
deleted file mode 100644
index 8713f3a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_exception_2.java
-.class public dot.junit.opcodes.move_exception.d.T_move_exception_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Z
-.limit regs 6
-
-Label1:
-       const v1, 1
-       const v2, 0
-       div-int v0, v1, v2 
-       
-Label2:
-       goto Label4
-
-Label3:
-       move-exception v3
-       const v4, 1
-       return v4
-
-Label4:
-       const v4, 0
-       return v4
-
-.catch java/lang/RuntimeException from Label1 to Label2 using Label3
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done
deleted file mode 100644
index e445cea..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_from16_1.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
-       const v10, 5678
-   
-       move/16 v4001, v10
-       
-       move/from16 v255, v4001
-       move/from16 v1, v255
-       
-       const/4 v4, 5678
-       
-       if-ne v1, v4, Label0
-       
-       const v1, 1
-       return v1
-
-Label0:
-       const v1, 0
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done
deleted file mode 100644
index 662e314..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_from16_6.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-       const-wide v4500, 123
-       move/from16 v0, v4500
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done
deleted file mode 100644
index 7d2f26c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_from16_7.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
-       const-wide v1234, 123
-       move/from16 v255, v1235
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done
deleted file mode 100644
index d41f1f7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_object_from16_6.java
-.class public dot.junit.opcodes.move_object_from16.d.T_move_object_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-       const-wide v4500, 123
-       move-object/from16 v0, v4500
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done
deleted file mode 100644
index 09abc65..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_object_from16_7.java
-.class public dot.junit.opcodes.move_object_from16.d.T_move_object_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
-       const-wide v1234, 123
-       move-object/from16 v255, v1235
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done
deleted file mode 100644
index 50c2eb2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done
+++ /dev/null
@@ -1,55 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_result_1.java
-.class public dot.junit.opcodes.move_result.d.T_move_result_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()Z
-.limit regs 16
-
-    const v0, 0
-    
-    invoke-static {} dot/junit/opcodes/move_result/d/T_move_result_1/foo()I
-
-    move-result v0
-    const v1, 12345
-    
-    if-eq v0, v1 Label1
-    
-    const v0, 0
-    return v0
-    
-Label1:
-    const v0, 1
-    return v0
-
-.end method
-
-.method private static foo()I
-.limit regs 1
-
-     const v0, 12345
-     return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done
deleted file mode 100644
index 4fecf88..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_6.java
-.class public dot.junit.opcodes.move_wide.d.T_move_wide_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()I
-.limit regs 9
-       const-wide v0, 1233746384323
-
-       move-wide v1, v0
-       
-       const-wide v4, 1233746384323
-       cmp-long v8, v1, v4
-       
-       return v8
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done
deleted file mode 100644
index aa8cdce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_16_9.java
-.class public dot.junit.opcodes.move_wide_16.d.T_move_wide_16_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()I
-.limit regs 5000
-       const-wide v1, 1233746384323
-       move-wide/16 v2, v1
-
-       const-wide v10, 1233746384323
-       cmp-long v4, v2, v10
-
-       return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done
deleted file mode 100644
index 21aaca8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_from16_1.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
-       const-wide v10, 5678233453
-   
-       move-wide/16 v4001, v10
-       
-       move-wide/from16 v255, v4001
-       move-wide/from16 v1, v255
-       
-       const-wide v4, 5678233453
-       
-       cmp-long v0, v1, v4
-       if-nez v0, Label0
-       
-       const v1, 1
-       return v1
-
-Label0:
-       const v1, 0
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done
deleted file mode 100644
index d2e6700..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_from16_2.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()I
-.limit regs 5000
-       const-wide v100, 5678233453
-       move-wide/from16 v101, v100
-       
-       const-wide v4, 5678233453
-       
-       cmp-long v0, v101, v4
-
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done
deleted file mode 100644
index 784e31a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_from16_6.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-       const v4500, 123
-       move-wide/from16 v0, v4500
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done
deleted file mode 100644
index 1790fe5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_move_wide_from16_7.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
-       const-wide v1234, 123
-       move-wide/from16 v255, v1235
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done
deleted file mode 100644
index f6f2588..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_new_array_7.java
-.class public dot.junit.opcodes.new_array.d.T_new_array_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)[Ljava/lang/Object;
-.limit regs 5
-
-       new-array v0, v4, java/lang/Object
-       return-object v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done
deleted file mode 100644
index 2a8eefb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_new_instance_2.java
-.class public dot.junit.opcodes.new_instance.d.T_new_instance_2
-.super java/lang/Object
-
-.field  i I
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static run()I
-.limit regs 5
-
-    new-instance v0, dot/junit/opcodes/new_instance/d/T_new_instance_2
-;    invoke-direct {v0}, dot/junit/opcodes/new_instance/d/T_new_instance_2/<init>()V
-
-    iget v1, v0, dot.junit.opcodes.new_instance.d.T_new_instance_2.i I
-
-    return v1
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done
deleted file mode 100644
index ea321c4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done
+++ /dev/null
@@ -1,22 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestAbstractClass.java
-.interface public dot.junit.opcodes.new_instance.d.TestInterface
-
-
-.source TestAbstractClass.java
-.class abstract public dot.junit.opcodes.new_instance.d.TestAbstractClass
-.super java/lang/Object
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done
deleted file mode 100644
index 8246f1b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_opc_const_1.java
-.class public dot.junit.opcodes.opc_const.d.T_opc_const_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()F
-.limit regs 3
-
-       const v1, 1.54
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done
deleted file mode 100644
index 1ab9dc1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_opc_return_3.java
-.class public dot.junit.opcodes.opc_return.d.T_opc_return_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private declared_synchronized test()F
-.limit regs 4
-
-    new-instance v2, java/lang/Object
-    invoke-direct {v2}, java/lang/Object/<init>()V
-    monitor-enter v2
-    monitor-exit v3
-    const v0, 1.0
-    return v0
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
-    invoke-direct {v0}, dot/junit/opcodes/opc_return/d/T_opc_return_3/test()F
-
-    const v0, 1
-    return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done
deleted file mode 100644
index 67366f6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_opc_throw_12.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Z
-.limit regs 2
-
-Label0:
-    invoke-direct {v1}, dot/junit/opcodes/opc_throw/d/T_opc_throw_12/test()Z
-    move-result v0
-    return v0
-Label1:
-    const v0, 0
-    return v0
-
-.catch java/lang/RuntimeException from Label0 to Label1 using Label1
-.end method
-
-
-.method private test()Z
-.limit regs 2
-Label0:
-    new-instance v0, java/lang/RuntimeException
-    invoke-direct {v0}, java/lang/RuntimeException/<init>()V
-    throw  v0
-Label1:
-    const v1, 1
-    return v1
-
-.catch java/lang/RuntimeException from Label0 to Label1 using Label1
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done
deleted file mode 100644
index f37a447..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_opc_throw_5.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public declared_synchronized run()V
-.limit regs 6
-
-       new-instance v2, java/lang/Object
-       invoke-direct {v2}, java/lang/Object/<init>()V
-       monitor-enter v2
-       monitor-exit v5
-
-       new-instance v1, java/lang/NullPointerException
-       invoke-direct {v1}, java/lang/NullPointerException/<init>()V
-       throw v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done
deleted file mode 100644
index bf85401..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_opc_throw_7.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
-       const v1, 3.14
-       throw v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done
deleted file mode 100644
index bd692e7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_1.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-       packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done
deleted file mode 100644
index d1d2d03..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_11.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done
deleted file mode 100644
index 58afb0b6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_12.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       goto Label0
-
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-       packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-Label0:       
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done
deleted file mode 100644
index 2e7471b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_13.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       goto Label0
-Label0:       
-       packed-switch v4, 0
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-       packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done
deleted file mode 100644
index a356eb3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_2.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(F)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done
deleted file mode 100644
index 79e9e8d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_3.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v5, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done
deleted file mode 100644
index 1c3d42b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_4.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)I
-.limit regs 5
-       packed-switch v3, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done
deleted file mode 100644
index c648fbb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_5.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(J)I
-.limit regs 5
-       packed-switch v3, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done
deleted file mode 100644
index 9a18602..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_6.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v3, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done
deleted file mode 100644
index ebf9766..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_7.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done
deleted file mode 100644
index b22771c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_8.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-        packed-switch-end
-Label6:
-       const v2, -1
-       return v2
-Label9:
-       const v2, 2
-       return v2
-Label12:
-       const v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done
deleted file mode 100644
index 217a917..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_packed_switch_9.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-       packed-switch v4, -1
-            Label9    ; -1
-            Label6    ; 0
-            Label6    ; 1
-            Label12    ; 2
-            Label12    ; 3
-       packed-switch-end
-Label6:
-       const/4 v2, -1
-       return v2
-Label9:
-       const/4 v2, 2
-       return v2
-Label12:
-       const/16 v2, 20
-       return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done
deleted file mode 100644
index ea4c11a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done
+++ /dev/null
@@ -1,43 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_object_12.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TSuper;
-.limit regs 5
-
-       new-instance v1, dot/junit/opcodes/return_object/d/TChild
-       invoke-direct {v1}, dot/junit/opcodes/return_object/d/TChild/<init>()V
-       return-object v1
-.end method
-
-.method public run()Z
-.limit regs 4
-
-       invoke-direct {v3}, dot/junit/opcodes/return_object/d/T_return_object_12/test()Ldot/junit/opcodes/return_object/d/TSuper;
-       move-result-object v2
-       instance-of v0, v2, dot/junit/opcodes/return_object/d/TChild
-       return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done
deleted file mode 100644
index 4cae4ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_object_13.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TInterface;
-.limit regs 5
-
-       new-instance v1, dot/junit/opcodes/return_object/d/TChild
-       invoke-direct {v1}, dot/junit/opcodes/return_object/d/TChild/<init>()V
-       return-object v1
-.end method
-
-.method public run()Z
-.limit regs 4
-Label0:
-
-       invoke-direct {v3}, dot/junit/opcodes/return_object/d/T_return_object_13/test()Ldot/junit/opcodes/return_object/d/TInterface;
-       move-result-object v2
-       instance-of v2, v2, dot/junit/opcodes/return_object/d/TChild
-       return v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done
deleted file mode 100644
index cff2b12..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_object_14.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TChild;
-.limit regs 6
-
-    new-instance v0, dot/junit/opcodes/return_object/d/TSuper
-    invoke-direct {v0}, dot/junit/opcodes/return_object/d/TSuper/<init>()V
-
-    return-object v0
-.end method
-
-
-.method public run()Z
-.limit regs 6
-
-    invoke-direct {v5}, dot/junit/opcodes/return_object/d/T_return_object_14/test()Ldot/junit/opcodes/return_object/d/TChild;
-    move-result-object v1
-
-    instance-of v0, v1, dot/junit/opcodes/return_object/d/TChild
-
-    return v0
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done
deleted file mode 100644
index 9b30169..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_object_4.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()F
-.limit regs 3
-
-      const v2, 3.14    
-      return-object v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done
deleted file mode 100644
index e82e7d6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_object_8.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private declared_synchronized test()Ljava/lang/String;
-.limit regs 4
-
-    new-instance v2, java/lang/Object
-    invoke-direct {v2}, java/lang/Object/<init>()V
-    monitor-enter v2
-    monitor-exit v3
-    const-string v0, "abc"
-    return-object v0
-.end method
-
-.method public run()Z
-.limit regs 3
-
-    invoke-direct {v2}, dot/junit/opcodes/return_object/d/T_return_object_8/test()Ljava/lang/String;
-
-    const v0, 1
-    return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done
deleted file mode 100644
index 44f819f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source TestStubs.java
-.interface dot.junit.opcodes.return_object.d.TInterface
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TSuper 
-.super java/lang/Object
-.implements dot.junit.opcodes.return_object.d.TInterface 
-    
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TChild 
-.super dot.junit.opcodes.return_object.d.TSuper 
-    
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, dot/junit/opcodes/return_object/d/TSuper/<init>()V
-       return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TSuper2
-.super java/lang/Object
- 
-    
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TestStubs 
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done
deleted file mode 100644
index b6bad32..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_void_3.java
-.class public dot.junit.opcodes.return_void.d.T_return_void_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private declared_synchronized test()V
-.limit regs 2
-
-    new-instance v0, java/lang/Object
-    invoke-direct {v0}, java/lang/Object/<init>()V
-    monitor-enter v0
-    monitor-exit v1
-    return-void
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
-    invoke-direct {v0}, dot/junit/opcodes/return_void/d/T_return_void_3/test()V
-
-    const v0, 1
-    return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done
deleted file mode 100644
index 479e777..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_return_wide_3.java
-.class public dot.junit.opcodes.return_wide.d.T_return_wide_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method private declared_synchronized test()D
-.limit regs 4
-
-    new-instance v2, java/lang/Object
-    invoke-direct {v2}, java/lang/Object/<init>()V
-    monitor-enter v2
-    monitor-exit v3
-    const-wide v0, 1.0
-    return-wide v0
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
-    invoke-direct {v0}, dot/junit/opcodes/return_wide/d/T_return_wide_3/test()D
-
-    const v0, 1
-    return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done
deleted file mode 100644
index 43ed17b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_14.java
-.class public dot.junit.opcodes.sget.d.T_sget_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget v0, dot.junit.opcodes.sget.d.T_sget_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done
deleted file mode 100644
index de5c7cb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_2.java
-.class public dot.junit.opcodes.sget.d.T_sget_2
-.super java/lang/Object
-
-.field public static val F
-
-.method static <clinit>()V
-.limit regs 2
-       const v0, 123.0
-       sput v0, dot.junit.opcodes.sget.d.T_sget_2.val F
-       return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()F
-.limit regs 4
-
-       sget v1, dot.junit.opcodes.sget.d.T_sget_2.val F
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done
deleted file mode 100644
index 831c623..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done
+++ /dev/null
@@ -1,52 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget.d.StubInitError
-.super java/lang/Object
-
-.field public static value I
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput v1, dot.junit.opcodes.sget.d.StubInitError.value I
-       return-void
-.end method
-
-
-.source T_sget_9.java
-.class public dot.junit.opcodes.sget.d.T_sget_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
-       sget v1, dot.junit.opcodes.sget.d.StubInitError.value I
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done
deleted file mode 100644
index 90de215..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_boolean_14.java
-.class public dot.junit.opcodes.sget_boolean.d.T_sget_boolean_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-boolean v0, dot.junit.opcodes.sget_boolean.d.T_sget_boolean_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done
deleted file mode 100644
index 0cf9a87..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_boolean.d.StubInitError
-.super java/lang/Object
-
-.field public static value Z
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 1
-       div-int/2addr v1, v0
-
-       const v1, 1
-       sput-boolean v1, dot.junit.opcodes.sget_boolean.d.StubInitError.value Z
-       return-void
-.end method
-
-
-.source T_sget_boolean_9.java
-.class public dot.junit.opcodes.sget_boolean.d.T_sget_boolean_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Z
-.limit regs 3
-
-       sget-boolean v1, dot.junit.opcodes.sget_boolean.d.StubInitError.value Z
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done
deleted file mode 100644
index d64eedc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_byte_14.java
-.class public dot.junit.opcodes.sget_byte.d.T_sget_byte_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-byte v0, dot.junit.opcodes.sget_byte.d.T_sget_byte_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done
deleted file mode 100644
index aee1a37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_byte.d.StubInitError
-.super java/lang/Object
-
-.field public static value B
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 1
-       div-int/2addr v1, v0
-
-       const v1, 1
-       sput-byte v1, dot.junit.opcodes.sget_byte.d.StubInitError.value B
-       return-void
-.end method
-
-
-.source T_sget_byte_9.java
-.class public dot.junit.opcodes.sget_byte.d.T_sget_byte_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()B
-.limit regs 3
-
-       sget-byte v1, dot.junit.opcodes.sget_byte.d.StubInitError.value B
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done
deleted file mode 100644
index c1b8040..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_char_14.java
-.class public dot.junit.opcodes.sget_char.d.T_sget_char_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-char v0, dot.junit.opcodes.sget_char.d.T_sget_char_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done
deleted file mode 100644
index cbb4a54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_char.d.StubInitError
-.super java/lang/Object
-
-.field public static value C
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 1
-       div-int/2addr v1, v0
-
-       const v1, 1
-       sput-char v1, dot.junit.opcodes.sget_char.d.StubInitError.value C
-       return-void
-.end method
-
-
-.source T_sget_char_9.java
-.class public dot.junit.opcodes.sget_char.d.T_sget_char_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()C
-.limit regs 3
-
-       sget-char v1, dot.junit.opcodes.sget_char.d.StubInitError.value C
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done
deleted file mode 100644
index e77f532..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_object_1.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_1
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-.field protected static p1 Ljava/lang/Object;
-.field private static pvt1 Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 1
-       const v0, 0
-       sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.i1 Ljava/lang/Object;
-
-       const v0, 0
-       sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.p1 Ljava/lang/Object;
-
-       const v0, 0
-       sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.pvt1 Ljava/lang/Object;
-
-       return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_1.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done
deleted file mode 100644
index ddb0713..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_object_21.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_21
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 1
-       new-instance v0, java/lang/Object
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       
-       sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_21.i1 Ljava/lang/Object;
-
-       return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 3
-
-       sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_21.i1 Ljava/lang/String;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done
deleted file mode 100644
index 498a01a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_object_3.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_3
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-object v3, dot.junit.opcodes.sget_object.d.T_sget_object_3.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done
deleted file mode 100644
index d00c4a0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_object_4.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_4
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_4.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done
deleted file mode 100644
index 35687ab..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_object_5.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_5
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 4
-
-       invoke-direct {v3}, java/lang/Object/<init>()V
-
-       const v2, 0
-       iput-object v2, v3, dot.junit.opcodes.sget_object.d.T_sget_object_5.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_5.i1 Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done
deleted file mode 100644
index efd184b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_object.d.StubInitError
-.super java/lang/Object
-
-.field public static value Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 1
-       div-int/2addr v1, v0
-
-       const v1, 0
-       sput-object v1, dot.junit.opcodes.sget_object.d.StubInitError.value Ljava/lang/Object;
-       return-void
-.end method
-
-
-.source T_sget_object_9.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
-       sget-object v1, dot.junit.opcodes.sget_object.d.StubInitError.value Ljava/lang/Object;
-       return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done
deleted file mode 100644
index 3d79cd1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_short_14.java
-.class public dot.junit.opcodes.sget_short.d.T_sget_short_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-short v0, dot.junit.opcodes.sget_short.d.T_sget_short_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done
deleted file mode 100644
index 85d6755..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_short.d.StubInitError
-.super java/lang/Object
-
-.field public static value S
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 1
-       div-int/2addr v1, v0
-
-       const v1, 1
-       sput-short v1, dot.junit.opcodes.sget_short.d.StubInitError.value S
-       return-void
-.end method
-
-
-.source T_sget_short_9.java
-.class public dot.junit.opcodes.sget_short.d.T_sget_short_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()S
-.limit regs 3
-
-       sget-short v1, dot.junit.opcodes.sget_short.d.StubInitError.value S
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done
deleted file mode 100644
index ffd5cb4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_wide_1.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_1
-.super java/lang/Object
-
-.field public static i1 J
-.field protected static p1 J
-.field private static pvt1 J
-
-.method static <clinit>()V
-.limit regs 2
-       const-wide v0, 12345679890123
-       sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.i1 J
-
-       const-wide v0, 10
-       sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.p1 J
-
-       const-wide v0, 20
-       sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.pvt1 J
-
-       return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
-       sget-wide v1, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.i1 J
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done
deleted file mode 100644
index 6e32d54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sget_wide_14.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sget-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_14.i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done
deleted file mode 100644
index e223578..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_wide.d.StubInitError
-.super java/lang/Object
-
-.field public static value J
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       const-wide v0, 1    
-       sput-wide v0, dot.junit.opcodes.sget_wide.d.StubInitError.value J
-       return-void
-.end method
-
-
-.source T_sget_wide_9.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
-       sget-wide v1, dot.junit.opcodes.sget_wide.d.StubInitError.value J
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done
deleted file mode 100644
index bd3aaa5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_1.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done
deleted file mode 100644
index 5853adb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_11.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done
deleted file mode 100644
index feff623..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_12.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_12
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done
deleted file mode 100644
index 8c7814d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_13.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_13
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-      goto Label0
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-Label0:
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done
deleted file mode 100644
index 074c119..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_14.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_14
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-      goto Label0
-Label0:
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done
deleted file mode 100644
index 0f8b90b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_2.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(F)I
-.limit regs 5
-
-Label3:
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done
deleted file mode 100644
index ce82bc9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_3.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-Label3:
-       sparse-switch v5
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done
deleted file mode 100644
index 36f8c8b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_4.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(D)I
-.limit regs 5
-
-Label3:
-       sparse-switch v3
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done
deleted file mode 100644
index dc72c30..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_5.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(J)I
-.limit regs 5
-
-Label3:
-       sparse-switch v3
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done
deleted file mode 100644
index 25e418f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_6.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-Label3:
-       sparse-switch v3
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done
deleted file mode 100644
index 67f3328..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_7.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done
deleted file mode 100644
index ba0dae3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_8.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done
deleted file mode 100644
index 2566813..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sparse_switch_9.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-       sparse-switch v4
-            -1 : Label9
-            10 : Label12
-            15 : Label12
-        sparse-switch-end
-Label6:
-       const v4, -1
-       return v4
-
-Label9:
-       const v4, 2
-       return v4
-
-Label12:
-       const v4, 20
-       return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done
deleted file mode 100644
index f6c9d9f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput.d.StubInitError
-.super java/lang/Object
-
-.field public static value I
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput v1, dot.junit.opcodes.sput.d.StubInitError.value I
-       return-void
-.end method
-
-
-.source T_sput_13.java
-.class public dot.junit.opcodes.sput.d.T_sput_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1000000
-       sput v1, dot.junit.opcodes.sput.d.StubInitError.value I
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done
deleted file mode 100644
index d0f53cf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_19.java
-.class public dot.junit.opcodes.sput.d.T_sput_19
-.super java/lang/Object
-
-.field public static st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-       sput v1, dot.junit.opcodes.sput.d.T_sput_19.st_f1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done
deleted file mode 100644
index 9229d34..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_20.java
-.class public dot.junit.opcodes.sput.d.T_sput_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const v3, 0
-       sput v3, dot.junit.opcodes.sput.d.T_sput_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done
deleted file mode 100644
index 0f89bc2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_boolean.d.StubInitError
-.super java/lang/Object
-
-.field public static value Z
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput-boolean v1, dot.junit.opcodes.sput_boolean.d.StubInitError.value Z
-       return-void
-.end method
-
-
-.source T_sput_boolean_13.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1
-       sput-boolean v1, dot.junit.opcodes.sput_boolean.d.StubInitError.value Z
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done
deleted file mode 100644
index f7922afb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_boolean_19.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_19
-.super java/lang/Object
-
-.field public static st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 3.14
-       sput-boolean v1, dot.junit.opcodes.sput_boolean.d.T_sput_boolean_19.st_f1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done
deleted file mode 100644
index abc0227..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_boolean_20.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const v3, 0    
-       sput-boolean v3, dot.junit.opcodes.sput_boolean.d.T_sput_boolean_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done
deleted file mode 100644
index 2271ca2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_byte.d.StubInitError
-.super java/lang/Object
-
-.field public static value B
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput-byte v1, dot.junit.opcodes.sput_byte.d.StubInitError.value B
-       return-void
-.end method
-
-
-.source T_sput_byte_13.java
-.class public dot.junit.opcodes.sput_byte.d.T_sput_byte_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1
-       sput-byte v1, dot.junit.opcodes.sput_byte.d.StubInitError.value B
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done
deleted file mode 100644
index 9a77ec6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_byte_20.java
-.class public dot.junit.opcodes.sput_byte.d.T_sput_byte_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       sput-byte v3, dot.junit.opcodes.sput_byte.d.T_sput_byte_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done
deleted file mode 100644
index 5b97bc4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_char.d.StubInitError
-.super java/lang/Object
-
-.field public static value C
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput-char v1, dot.junit.opcodes.sput_char.d.StubInitError.value C
-       return-void
-.end method
-
-
-.source T_sput_char_13.java
-.class public dot.junit.opcodes.sput_char.d.T_sput_char_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1
-       sput-char v1, dot.junit.opcodes.sput_char.d.StubInitError.value C
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done
deleted file mode 100644
index 92d2e6e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_char_20.java
-.class public dot.junit.opcodes.sput_char.d.T_sput_char_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       sput-char v3, dot.junit.opcodes.sput_char.d.T_sput_char_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done
deleted file mode 100644
index acb4903..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_1.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_1
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-.field protected static st_p1 Ljava/lang/Object;
-.field private static st_pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static getPvtField()Ljava/lang/Object;
-.limit regs 2
-
-       sget-object v0, dot.junit.opcodes.sput_object.d.T_sput_object_1.st_pvt1 Ljava/lang/Object;
-       return-object v0
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_1.st_i1 Ljava/lang/Object;
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done
deleted file mode 100644
index 7f12b99..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_10.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_10
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_10.st_i1N Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done
deleted file mode 100644
index 562d8edb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_12.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_12
-.super java/lang/Object
-
-.field public static final st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_12.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done
deleted file mode 100644
index d2d59da..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_object.d.StubInitError
-.super java/lang/Object
-
-.field public static t I
-.field public static value Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput v1, dot.junit.opcodes.sput_object.d.StubInitError.t I
-       return-void
-.end method
-
-
-.source T_sput_object_13.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.StubInitError.value Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done
deleted file mode 100644
index 5b6c088..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_2.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_2
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v0, 1234    
-       sput-object v0, dot.junit.opcodes.sput_object.d.T_sput_object_2.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done
deleted file mode 100644
index 8d6c9df..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_20.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/String;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       sput-object v3, dot.junit.opcodes.sput_object.d.T_sput_object_20.st_o Ljava/lang/String;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done
deleted file mode 100644
index 080efbc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_3.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_3
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-        sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_3.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done
deleted file mode 100644
index 3a3bccd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_4.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_4
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v3, dot.junit.opcodes.sput_object.d.T_sput_object_4.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done
deleted file mode 100644
index 84988f9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_7.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_7
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_7.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done
deleted file mode 100644
index 2d35cf1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_object_9.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_9
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_9noclass.st_i1 Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done
deleted file mode 100644
index 55d0bf5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_short.d.StubInitError
-.super java/lang/Object
-
-.field public static value S
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       sput-short v1, dot.junit.opcodes.sput_short.d.StubInitError.value S
-       return-void
-.end method
-
-
-.source T_sput_short_13.java
-.class public dot.junit.opcodes.sput_short.d.T_sput_short_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1
-       sput-short v1, dot.junit.opcodes.sput_short.d.StubInitError.value S
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done
deleted file mode 100644
index dc42d54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_short_20.java
-.class public dot.junit.opcodes.sput_short.d.T_sput_short_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       sput-short v3, dot.junit.opcodes.sput_short.d.T_sput_short_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done
deleted file mode 100644
index 94e2898..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_wide_1.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_1
-.super java/lang/Object
-
-.field public static st_i1 J
-.field protected static st_p1 J
-.field private static st_pvt1 J
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public static getPvtField()J
-.limit regs 2
-
-       sget-wide v0, dot.junit.opcodes.sput_wide.d.T_sput_wide_1.st_pvt1 J
-       return-wide v0
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v1, 778899112233
-       sput-wide v1, dot.junit.opcodes.sput_wide.d.T_sput_wide_1.st_i1 J
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done
deleted file mode 100644
index ae7d1df..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done
+++ /dev/null
@@ -1,54 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source JtubInitError.java
-.class public dot.junit.opcodes.sput_wide.d.JtubInitError
-.super java/lang/Object
-
-.field public static value J
-
-.method static <clinit>()V
-.limit regs 2
-
-       const/4 v0, 0
-       const/4 v1, 5
-       div-int/2addr v1, v0
-
-       int-to-long v0, v0
-       sput-wide v0, dot.junit.opcodes.sput_wide.d.JtubInitError.value J
-       return-void
-.end method
-
-
-.source T_sput_wide_13.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v1, 1
-       sput-wide v1, dot.junit.opcodes.sput_wide.d.JtubInitError.value J
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done
deleted file mode 100644
index 463bdbd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_wide_18.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_18
-.super java/lang/Object
-
-.field public static st_i1 F
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const v1, 1.0
-       sput-wide v1, dot.junit.opcodes.sput_wide.d.T_sput_wide_18.st_i1 F
-
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done
deleted file mode 100644
index ca43933..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sput_wide_20.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       sput-wide v3, dot.junit.opcodes.sput_wide.d.T_sput_wide_20.st_o Ljava/lang/Object;
-       return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done
deleted file mode 100644
index e202f3c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sub_double_2.java
-.class public dot.junit.opcodes.sub_double.d.T_sub_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
-       const v3, 3.1415
-       sub-double v0, v3, v5
-       return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done
deleted file mode 100644
index 0b37443c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sub_double_2addr_2.java
-.class public dot.junit.opcodes.sub_double_2addr.d.T_sub_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
-       const v3, 3.1415
-       sub-double/2addr v3, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done
deleted file mode 100644
index 7ab2d2d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sub_long_4.java
-.class public dot.junit.opcodes.sub_long.d.T_sub_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-       const v5, 12346.0
-       sub-long v0, v3, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done
deleted file mode 100644
index 57d6c24..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_sub_long_2addr_4.java
-.class public dot.junit.opcodes.sub_long_2addr.d.T_sub_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-       const v5, 12346.0
-       sub-long/2addr v3, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done
deleted file mode 100644
index d0b5a53..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_ushr_int_lit8_11.java
-.class public dot.junit.opcodes.ushr_int_lit8.d.T_ushr_int_lit8_11
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()I
-.limit regs 4
-       const-wide v0, 12345456788
-       ushr-int/lit8 v1, v0, 1
-       return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done
deleted file mode 100644
index 03ae1aa..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_ushr_long_4.java
-.class public dot.junit.opcodes.ushr_long.d.T_ushr_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JI)J
-.limit regs 6
-
-       const v0, 12345.0
-       ushr-long v0, v0, v5
-       return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done
deleted file mode 100644
index 4f03522..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_ushr_long_2addr_4.java
-.class public dot.junit.opcodes.ushr_long_2addr.d.T_ushr_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JI)J
-.limit regs 4
-
-       const v1, 12345.0
-       ushr-long/2addr v1, v3
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done
deleted file mode 100644
index 28e9fff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_xor_long_4.java
-.class public dot.junit.opcodes.xor_long.d.T_xor_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 5
-
-       const v3, 1234.0
-       xor-long v1, v1, v3
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done
deleted file mode 100644
index 98c0cd8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_xor_long_2addr_4.java
-.class public dot.junit.opcodes.xor_long_2addr.d.T_xor_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 5
-
-       const v3, 1234.0
-       xor-long/2addr v1, v3
-       return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done
deleted file mode 100644
index 1fe908a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_b2_1.java
-.class public dot.junit.verify.b2.d.T_b2_1
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v0, 123
-       move v1, v0 ; illegal read access to v1
-       return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done
deleted file mode 100644
index a885c41..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_b2_2.java
-.class public dot.junit.verify.b2.d.T_b2_2
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
-       const-wide v0, 123 
-       move v0, v1 ; // illegal read access to v0
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done
deleted file mode 100644
index bf8d6e0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_b2_3.java
-.class public dot.junit.verify.b2.d.T_b2_3
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
-       const v0, 123 
-       const v1, 123 
-       move-wide v2, v0 ; // illegal read access to v0/1
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done
deleted file mode 100644
index bb158ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_b2_4.java
-.class public dot.junit.verify.b2.d.T_b2_4
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
-       const-wide v0, 123
-       move v2, v0 ; // illegal read access to v0
-       return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done
deleted file mode 100644
index 483066d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; Copyright (C) 2008 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.
-
-.source T_b2_5.java
-.class public dot.junit.verify.b2.d.T_b2_5
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
-       invoke-direct {v0}, java/lang/Object/<init>()V
-       return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
-       const-wide v0, 123
-       move-wide v2, v0
-       move-wide v2, v1 ; // illegal read access to v1/2
-       return-void
-.end method
-