Snap for 6227479 from 0fb562077c998f1fa90b0e3be5436bb122bf9b3c to rvc-release

Change-Id: I252b428967ddd83dd32750c488a557edc252f6c3
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 976bee0..75b7a5d 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -30,6 +30,7 @@
 ALIGN_TOL = 0.01  # multiplied by sensor diagonal to convert to pixels
 CIRCLE_RTOL = 0.1
 GYRO_REFERENCE = 1
+LENS_FACING_BACK = 1  # 0: FRONT, 1: BACK, 2: EXTERNAL
 UNDEFINED_REFERENCE = 2
 NAME = os.path.basename(__file__).split('.')[0]
 TRANS_REF_MATRIX = np.array([0, 0, 0])
@@ -333,7 +334,7 @@
                              its.caps.logical_multi_camera(props))
 
         # Convert chart_distance for lens facing back
-        if props['android.lens.facing']:
+        if props['android.lens.facing'] == LENS_FACING_BACK:
             # API spec defines +z is pointing out from screen
             print 'lens facing BACK'
             chart_distance *= -1
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
index 272a9fc..a0a715f 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
@@ -32,6 +32,8 @@
             android:orientation="vertical"
         >
 
+            <include layout="@layout/audio_refmic_layout"/>
+
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
index 435f5a7..a9aeafa 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
@@ -30,70 +30,72 @@
             android:layout_height="wrap_content"
             android:orientation="vertical">
 
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:scrollbars="vertical"
-            android:gravity="bottom"
-            android:id="@+id/info_text"
-            android:text="@string/audio_frequency_speaker_instructions"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <Button
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:id="@+id/audio_frequency_speaker_mic_ready_btn"
-                android:text="@string/audio_frequency_speaker_mic_ready_btn"
-                android:nextFocusForward="@+id/audio_frequency_speaker_test_btn"
-                android:nextFocusDown="@+id/audio_frequency_speaker_test_btn"
-                android:nextFocusRight="@+id/audio_frequency_speaker_test_btn" />
+            <include layout="@layout/audio_refmic_layout"/>
 
             <TextView
-                android:layout_width="wrap_content"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/audio_frequency_speaker_usb_status"
-                android:id="@+id/audio_frequency_speaker_usb_status"/>
+                android:scrollbars="vertical"
+                android:gravity="bottom"
+                android:id="@+id/info_text"
+                android:text="@string/audio_frequency_speaker_instructions"/>
 
             <LinearLayout
-                android:orientation="vertical"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-                <LinearLayout
-                    android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+                <Button
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:id="@+id/audio_frequency_speaker_layout">
-                    <Button
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:text="@string/audio_frequency_speaker_test_btn"
-                        android:id="@+id/audio_frequency_speaker_test_btn"
-                        android:nextFocusForward="@+id/pass_button"
-                        android:nextFocusUp="@+id/audio_frequency_speaker_mic_ready_btn"
-                        android:nextFocusDown="@+id/pass_button"
-                        android:nextFocusLeft="@+id/audio_frequency_speaker_mic_ready_btn"
-                        android:nextFocusRight="@+id/pass_button" />
-
-                    <ProgressBar
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:id="@+id/audio_frequency_speaker_progress_bar"/>
-                </LinearLayout>
+                    android:id="@+id/audio_frequency_speaker_mic_ready_btn"
+                    android:text="@string/audio_frequency_speaker_mic_ready_btn"
+                    android:nextFocusForward="@+id/audio_frequency_speaker_test_btn"
+                    android:nextFocusDown="@+id/audio_frequency_speaker_test_btn"
+                    android:nextFocusRight="@+id/audio_frequency_speaker_test_btn" />
 
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/audio_frequency_speaker_results_text"
-                    android:id="@+id/audio_frequency_speaker_results_text"/>
+                    android:text="@string/audio_frequency_speaker_usb_status"
+                    android:id="@+id/audio_frequency_speaker_usb_status"/>
 
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent">
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:orientation="horizontal"
+                        android:id="@+id/audio_frequency_speaker_layout">
+                        <Button
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/audio_frequency_speaker_test_btn"
+                            android:id="@+id/audio_frequency_speaker_test_btn"
+                            android:nextFocusForward="@+id/pass_button"
+                            android:nextFocusUp="@+id/audio_frequency_speaker_mic_ready_btn"
+                            android:nextFocusDown="@+id/pass_button"
+                            android:nextFocusLeft="@+id/audio_frequency_speaker_mic_ready_btn"
+                            android:nextFocusRight="@+id/pass_button" />
+
+                        <ProgressBar
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:id="@+id/audio_frequency_speaker_progress_bar"/>
+                    </LinearLayout>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_frequency_speaker_results_text"
+                        android:id="@+id/audio_frequency_speaker_results_text"/>
+
+                </LinearLayout>
             </LinearLayout>
-        </LinearLayout>
 
-        <include layout="@layout/pass_fail_buttons"/>
+            <include layout="@layout/pass_fail_buttons"/>
         </LinearLayout>
       </ScrollView>
 
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
index d02ef0b..8032f93 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
@@ -23,6 +23,8 @@
             android:layout_height="wrap_content"
             android:orientation="vertical">
 
+            <include layout="@layout/audio_refmic_layout"/>
+
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
index c6cd0cd..1ccd947 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
@@ -31,6 +31,8 @@
             android:layout_height="wrap_content"
             android:orientation="vertical">
 
+            <include layout="@layout/audio_refmic_layout"/>
+
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_refmic_layout.xml b/apps/CtsVerifier/res/layout/audio_refmic_layout.xml
new file mode 100644
index 0000000..bd806a1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_refmic_layout.xml
@@ -0,0 +1,38 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/refmic_test_question"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:soundEffectsEnabled="false"
+            android:text="@string/refmic_test_yes"
+            android:id="@+id/refmic_tests_yes_btn" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:soundEffectsEnabled="false"
+            android:text="@string/refmic_test_no"
+            android:id="@+id/refmic_tests_no_btn" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:soundEffectsEnabled="false"
+            android:text="@string/refmic_test_info"
+            android:id="@+id/refmic_test_info_btn" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 67eeeca..4f9cc0a9 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -5423,4 +5423,17 @@
     Note: Handheld devices supporting USB host mode MUST support USB audio class (CDD 7.7 .2/H-1-1)\n
     Note: Devices declaring feature android.hardware.audio.pro MUST implement USB host mode (CDD 5.10 C-1-3) and if they omit a 4 conductor 3.5mm audio jack MUST support USB audio class (CDD 5.10 C-3-1)
     </string>
+
+    <string name="refmic_test_no">No</string>
+    <string name="refmic_test_yes">Yes</string>
+    <string name="refmic_test_info">Info</string>
+    <string name="refmic_test_question">Does this device allow for the connection of a USB reference microphone?</string>
+    <string name="ref_mic_dlg_caption">Reference Mic Required</string>
+    <string name="ref_mic_dlg_text">This test requires a USB Reference Mic to be connected to the device.
+    If the device under test does not support USB Host Mode Audio (either because it does not have a
+    USB port, or USB Host Mode Audio has been removed from the OS) you can be granted a provisional
+    pass on this test by pressing the \"No\" button and indicating \"Test Pass\" at the bottom.\n
+    Note: Handheld devices supporting USB host mode MUST support USB audio class (CDD 7.7 .2/H-1-1)\n
+    Note: Devices declaring feature android.hardware.audio.pro MUST implement USB host mode (CDD 5.10 C-1-3) and if they omit a 4 conductor 3.5mm audio jack MUST support USB audio class (CDD 5.10 C-3-1)
+    </string>
 </resources>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
index 3b97e37..ffc5f41 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
@@ -53,6 +53,65 @@
 
     public int mMaxLevel = 0;
 
+    private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    //
+    // Common UI Handling
+    protected void connectRefMicUI() {
+        findViewById(R.id.refmic_tests_yes_btn).setOnClickListener(mBtnClickListener);
+        findViewById(R.id.refmic_tests_no_btn).setOnClickListener(mBtnClickListener);
+        findViewById(R.id.refmic_test_info_btn).setOnClickListener(mBtnClickListener);
+
+        enableTestUI(false);
+    }
+
+    private void showRefMicInfoDialog() {
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.ref_mic_dlg_caption)
+                .setMessage(R.string.ref_mic_dlg_text)
+                .setPositiveButton(R.string.audio_general_ok, null)
+                .show();
+    }
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.refmic_tests_yes_btn:
+                    recordRefMicStatus(true);
+                    enableTestUI(true);
+                    // disable test button so that they will now run the test(s)
+                    getPassButton().setEnabled(false);
+                    break;
+
+                case R.id.refmic_tests_no_btn:
+                    recordRefMicStatus(false);
+                    enableTestUI(false);
+                    // Allow the user to "pass" the test.
+                    getPassButton().setEnabled(true);
+                    break;
+
+                case R.id.refmic_test_info_btn:
+                    showRefMicInfoDialog();
+                    break;
+            }
+        }
+    }
+
+    private void recordRefMicStatus(boolean has) {
+        getReportLog().addValue(
+                "User reported ref mic availability: ",
+                has ? 1.0 : 0,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+    }
+
+    //
+    // Overrides
+    //
+    void enableTestUI(boolean enable) {
+
+    }
+
     public void setMaxLevel() {
         AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
         mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
index 129fb72..e296f86 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
@@ -238,7 +238,22 @@
                 5.0, -50.0,      /* start top,bottom value */
                 5.0, -50.0      /* stop top,bottom value */);
 
+        connectRefMicUI();
     }
+
+    //
+    // Overrides
+    //
+    void enableTestUI(boolean enable) {
+        mButtonTestNoise.setEnabled(enable);
+        mButtonPlayNoise.setEnabled(enable);
+
+        mButtonTestUsbBackground.setEnabled(enable);
+
+        mButtonTestUsbNoise.setEnabled(enable);
+        mButtonPlayUsbNoise.setEnabled(enable);
+    }
+
     private void playerToggleButton(int buttonId) {
         if (playerIsPlaying()) {
             playerStopAll();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
index 294e48d..f954b0c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -205,6 +205,15 @@
                 5.0, -50.0,      /* start top,bottom value */
                 5.0, -50.0      /* stop top,bottom value */);
 
+        connectRefMicUI();
+    }
+
+    //
+    // Overrides
+    //
+    void enableTestUI(boolean enable) {
+        mLoopbackPlugReady.setEnabled(enable);
+        mTestButton.setEnabled(enable);
     }
 
     /**
@@ -212,8 +221,8 @@
      */
     private void enableLayout(boolean enable) {
         for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
-            View view = mLinearLayout.getChildAt(i);
-            view.setEnabled(enable);
+            mLoopbackPlugReady.setEnabled(enable);
+            mTestButton.setEnabled(enable);
         }
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
index 009dd58..fb8460b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
@@ -292,6 +292,24 @@
         mResultsMic =  new Results("mic_response", mBands);
         mResultsTone = new Results("tone_response", mBandsTone);
         mResultsBack = new Results("background_response", mBandsBack);
+
+        connectRefMicUI();
+    }
+
+    //
+    // Overrides
+    //
+    void enableTestUI(boolean enable) {
+        mButtonTestTone.setEnabled(enable);
+        mButtonPlayTone.setEnabled(enable);
+
+        mButtonTestNoise.setEnabled(enable);
+        mButtonPlayNoise.setEnabled(enable);
+
+        mButtonTestUsbBackground.setEnabled(enable);
+
+        mButtonTestUsbNoise.setEnabled(enable);
+        mButtonPlayUsbNoise.setEnabled(enable);
     }
 
     private void playerToggleButton(int buttonId, int sourceId) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
index 4017973..efe666a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
@@ -329,6 +329,23 @@
         mResultsMic = new Results("mic_response", BANDS_MIC);
         mResultsTone = new Results("tone_response", BANDS_TONE);
         mResultsBack = new Results("background_response", BANDS_BACKGROUND);
+        connectRefMicUI();
+    }
+
+    //
+    // Overrides
+    //
+    void enableTestUI(boolean enable) {
+        mButtonTestTone.setEnabled(enable);
+        mButtonPlayTone.setEnabled(enable);
+
+        mButtonTestNoise.setEnabled(enable);
+        mButtonPlayNoise.setEnabled(enable);
+
+        mButtonTestUsbBackground.setEnabled(enable);
+
+        mButtonTestUsbNoise.setEnabled(enable);
+        mButtonPlayUsbNoise.setEnabled(enable);
     }
 
     private void playerToggleButton(int buttonId, int sourceId) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
index a679c41..b62a986 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
@@ -47,6 +47,11 @@
     private static final String mBuiltInprofiles =
         "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" +
             "<ProfileList Version=\"1.0.0\">" +
+            "<PeripheralProfile ProfileName=\"Google USB-C Headset\" ProfileDescription=\"Google USB-C Headset\" ProductName=\"USB-Audio - Pixel USB-C earbuds\">" +
+                "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
+                "<InputDevInfo ChanCounts=\"1\" ChanPosMasks=\"16\" ChanIndexMasks=\"1\" Encodings=\"2\" SampleRates=\"44100,48000\" />" +
+                "<ButtonInfo HasBtnA=\"1\" HasBtnB=\"1\" HasBtnC=\"1\" HasBtnD=\"0\" />" +
+            "</PeripheralProfile>" +
             "<PeripheralProfile ProfileName=\"AudioBox USB 96\" ProfileDescription=\"PreSonus AudioBox USB 96\" ProductName=\"USB-Audio - AudioBox USB 96\">" +
                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\"/>" +
                 "<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"1,3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\"/>" +
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
index 7730b17..473579f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
@@ -59,10 +59,18 @@
             final BiometricManager bm = getSystemService(BiometricManager.class);
 
             final int biometricResult = bm.canAuthenticate(Authenticators.BIOMETRIC_WEAK);
-            if (biometricResult != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
-                showToastAndLog("Unexpected result: " + biometricResult +
-                        ". Please make sure the device does not have a biometric enrolled");
-                return;
+            switch (biometricResult) {
+                case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
+                case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
+                    // OK
+                    break;
+                case BiometricManager.BIOMETRIC_SUCCESS:
+                    showToastAndLog("Unexpected result: " + biometricResult +
+                            ". Please make sure the device does not have a biometric enrolled");
+                    return;
+                default:
+                    showToastAndLog("Unexpected result: " + biometricResult);
+                    return;
             }
 
             final int credentialResult = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
diff --git a/hostsidetests/blobstore/Android.bp b/hostsidetests/blobstore/Android.bp
index 398aff8..aab448e 100644
--- a/hostsidetests/blobstore/Android.bp
+++ b/hostsidetests/blobstore/Android.bp
@@ -31,8 +31,8 @@
 }
 
 android_test_helper_app {
-  name: "CtsBlobStoreHelperApp",
-  srcs:  ["test-apps/BlobStoreHelperApp/src/**/*.java"],
+  name: "CtsBlobStoreHostTestHelper",
+  srcs:  ["test-apps/BlobStoreHostTestHelper/src/**/*.java"],
   static_libs: [
       "compatibility-device-util-axt",
       "androidx.test.ext.junit",
@@ -41,7 +41,7 @@
       "truth-prebuilt",
       "testng",
   ],
-  manifest : "test-apps/BlobStoreHelperApp/AndroidManifest.xml",
+  manifest : "test-apps/BlobStoreHostTestHelper/AndroidManifest.xml",
   platform_apis: true,
   // Tag this module as a cts test artifact
   test_suites: [
diff --git a/hostsidetests/blobstore/AndroidTest.xml b/hostsidetests/blobstore/AndroidTest.xml
index eaa301d..b1b6d63 100644
--- a/hostsidetests/blobstore/AndroidTest.xml
+++ b/hostsidetests/blobstore/AndroidTest.xml
@@ -24,7 +24,7 @@
         <option name="jar" value="CtsBlobStoreHostTestCases.jar" />
     </test>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="CtsBlobStoreHelperApp.apk" />
+        <option name="test-file-name" value="CtsBlobStoreHostTestHelper.apk" />
         <option name="cleanup-apks" value="true" />
     </target_preparer>
 </configuration>
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
index 9e3701d..7d25f5d 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
@@ -27,6 +27,9 @@
 import java.util.stream.Collectors;
 
 abstract class BaseBlobStoreHostTest extends BaseHostJUnit4Test {
+    protected static final String TARGET_APK = "CtsBlobStoreHostTestHelper.apk";
+    protected static final String TARGET_PKG = "com.android.cts.device.blob";
+
     private static final long TIMEOUT_BOOT_COMPLETE_MS = 120_000;
 
     protected static final String KEY_SESSION_ID = "session";
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
index 9f58c3e..d8cc1a0 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
@@ -31,8 +31,6 @@
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class BlobStoreMultiUserTest extends BaseBlobStoreHostTest {
-    private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
-    private static final String TARGET_PKG = "com.android.cts.blob.helper";
     private static final String TEST_CLASS = TARGET_PKG + ".DataCleanupTest";
 
     private int mPrimaryUserId;
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
index 8a3efc8..291bc7c 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
@@ -24,8 +24,6 @@
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class DataCleanupTest extends BaseBlobStoreHostTest {
-    private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
-    private static final String TARGET_PKG = "com.android.cts.blob.helper";
     private static final String TEST_CLASS = TARGET_PKG + ".DataCleanupTest";
 
     @Test
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
index 39f9b32..973ca8b 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
@@ -22,8 +22,6 @@
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class DataPersistenceTest extends BaseBlobStoreHostTest {
-    private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
-    private static final String TARGET_PKG = "com.android.cts.blob.helper";
     private static final String TEST_CLASS = TARGET_PKG + ".DataPersistenceTest";
 
     @Test
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
similarity index 88%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
index a649209..36e0a9b 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
@@ -15,12 +15,12 @@
  * limitations under the License.
  -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.cts.blob.helper">
+          package="com.android.cts.device.blob">
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation
             android:name="androidx.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.blob.helper"  />
+            android:targetPackage="com.android.cts.device.blob"  />
 </manifest>
\ No newline at end of file
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
similarity index 99%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
index 00467cd..5bb82b9 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.blob.helper;
+package com.android.cts.device.blob;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
similarity index 99%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
index 5cfd669..b4226a6 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.blob.helper;
+package com.android.cts.device.blob;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/hostsidetests/bootstats/Android.bp b/hostsidetests/bootstats/Android.bp
index ca1e292..07f9c84 100644
--- a/hostsidetests/bootstats/Android.bp
+++ b/hostsidetests/bootstats/Android.bp
@@ -17,12 +17,12 @@
     defaults: ["cts_defaults"],
     // Only compile source java files in this apk.
     srcs: ["src/**/*.java"],
-    static_libs: ["framework-protos"],
     libs: [
         "cts-tradefed",
         "tradefed",
         "compatibility-host-util",
         "libprotobuf-java-full",
+        "platformprotos",
     ],
     // tag this module as a cts test artifact
     test_suites: [
diff --git a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
index 9ec3dad..e5eb36c 100644
--- a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
+++ b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
@@ -16,7 +16,7 @@
 
 package android.bootstats.cts;
 
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.os.AtomsProto.Atom;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -56,37 +56,53 @@
         Thread.sleep(10000);
 
         // find logs and parse them
-        // ex: sysui_multi_action: [757,804,799,ota_boot_complete,801,85,802,1]
-        // ex: 757,804,799,counter_name,801,bucket_value,802,increment_value
-        final String bucketTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
-        final String counterNameTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME);
-        final String counterNamePattern = counterNameTag + ",boot_complete,";
-        final String multiActionPattern = "sysui_multi_action: [";
+        // ex: Atom 239->10
+        // ex: Atom 240->9
+         final String bootTimeEventDurationReported =
+                Integer.toString(Atom.BOOT_TIME_EVENT_DURATION_REPORTED_FIELD_NUMBER);
+        final String bootTimeEventDurationReportedPattern = "Atom "
+                + bootTimeEventDurationReported + "->";
+        final String bootTimeEventElapsedTimeReported =
+                Integer.toString(Atom.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED_FIELD_NUMBER);
+        final String bootTimeEventElapsedTimeReportedPattern = "Atom "
+                + bootTimeEventElapsedTimeReported + "->";
 
-        final String log = getDevice().executeShellCommand("logcat --buffer=events -d");
+        final String log = getDevice().executeShellCommand("cmd stats print-stats");
 
-        int counterNameIndex = log.indexOf(counterNamePattern);
-        Assert.assertTrue("did not find boot logs", counterNameIndex != -1);
+        int bootTimeEventDurationReportedIndex =
+                log.indexOf(bootTimeEventDurationReportedPattern);
+        Assert.assertTrue("did not find boot duration logs",
+                bootTimeEventDurationReportedIndex != -1);
+        // extract the number after ->, e.g., 10 inside 239->10
+        int valueIndex = bootTimeEventDurationReportedIndex +
+                bootTimeEventDurationReportedPattern.length();
+        int value = getIntValue(log, valueIndex);
+        Assert.assertTrue("boot duration time smaller than 1", value > 1);
 
-        int multiLogStart = log.lastIndexOf(multiActionPattern, counterNameIndex);
-        multiLogStart += multiActionPattern.length();
-        int multiLogEnd = log.indexOf("]", multiLogStart);
-        String[] multiLogDataStrings = log.substring(multiLogStart, multiLogEnd).split(",");
+        int bootTimeEventElapsedTimeReportedIndex =
+                log.indexOf(bootTimeEventElapsedTimeReportedPattern);
+        Assert.assertTrue("did not find boot elapsed time logs",
+                bootTimeEventElapsedTimeReportedIndex != -1);
 
-        boolean foundBucket = false;
-        int bootTime = 0;
-        for (int i = 0; i < multiLogDataStrings.length; i += 2) {
-            if (bucketTag.equals(multiLogDataStrings[i])) {
-                foundBucket = true;
-                Assert.assertTrue("histogram data was truncated",
-                        (i + 1) < multiLogDataStrings.length);
-                bootTime = Integer.valueOf(multiLogDataStrings[i + 1]);
+        // extract the number after ->, e.g., 9 inside Atom 240->9
+        valueIndex = bootTimeEventElapsedTimeReportedIndex +
+                bootTimeEventElapsedTimeReportedPattern.length();
+        value = getIntValue(log, valueIndex);
+        Assert.assertTrue("boot elapsed time smaller than 1", value > 1);
+    }
+
+    // extract the value from the string starting from index till EOL
+    private int getIntValue(String str, int index) throws Exception {
+        int lastIndex = index;
+        for (int i = index; i < str.length(); i++) {
+            if (str.charAt(i) == '\n') {
+                lastIndex = i;
+                break;
             }
         }
-        Assert.assertTrue("log line did not contain a tag " + bucketTag, foundBucket);
-        Assert.assertTrue("reported boot time must be less than observed boot time",
-                bootTime < upperBoundSeconds);
-        Assert.assertTrue("reported boot time must be non-zero", bootTime > 0);
+        String valueStr = str.substring(index, lastIndex);
+        int value = Integer.valueOf(valueStr);
+        return value;
     }
 
     private boolean isBootCompleted() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 212d20f..889e91a 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -69,6 +69,7 @@
     protected DevicePolicyManager mDevicePolicyManager;
     protected UserManager mUserManager;
     protected Context mContext;
+    protected boolean mHasSecureLockScreen;
     static CountDownLatch mOnPasswordExpiryTimeoutCalled;
 
     private final String mTag = getClass().getSimpleName();
@@ -84,6 +85,9 @@
         mUserManager = mContext.getSystemService(UserManager.class);
         assertNotNull(mUserManager);
 
+        mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SECURE_LOCK_SCREEN);
+
         assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
         assertTrue("App is neither device nor profile owner",
                 mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
similarity index 83%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
index ed4c19f..58a377e 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
 
 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
@@ -62,16 +62,21 @@
 import android.content.SharedPreferences;
 import android.os.Parcel;
 import android.os.Process;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
+import android.text.TextUtils;
+import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
+import junit.framework.AssertionFailedError;
+
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
@@ -85,7 +90,8 @@
 
 import javax.crypto.spec.SecretKeySpec;
 
-public class SecurityLoggingTest extends BaseDeviceOwnerTest {
+public class SecurityLoggingTest extends BaseDeviceAdminTest {
+    private static final String TAG = "SecurityLoggingTest";
     private static final String ARG_BATCH_NUMBER = "batchNumber";
     private static final String PREF_KEY_PREFIX = "batch-last-id-";
     private static final String PREF_NAME = "batchIds";
@@ -123,8 +129,8 @@
                     .put(TAG_KEY_GENERATED, of(I, S, I))
                     .put(TAG_KEY_IMPORT, of(I, S, I))
                     .put(TAG_KEY_DESTRUCTION, of(I, S, I))
-                    .put(TAG_CERT_AUTHORITY_INSTALLED, of(I, S))
-                    .put(TAG_CERT_AUTHORITY_REMOVED, of(I, S))
+                    .put(TAG_CERT_AUTHORITY_INSTALLED, of(I, S, I))
+                    .put(TAG_CERT_AUTHORITY_REMOVED, of(I, S, I))
                     .put(TAG_USER_RESTRICTION_ADDED, of(S, I, S))
                     .put(TAG_USER_RESTRICTION_REMOVED, of(S, I, S))
                     .put(TAG_CRYPTO_SELF_TEST_COMPLETED, of(I))
@@ -170,6 +176,7 @@
     private static final int SUCCESS_INDEX = 0;
     private static final int ALIAS_INDEX = 1;
     private static final int UID_INDEX = 2;
+    private static final int USERID_INDEX = 2;
     private static final int SUBJECT_INDEX = 1;
     private static final int ADMIN_PKG_INDEX = 0;
     private static final int ADMIN_USER_INDEX = 1;
@@ -208,7 +215,7 @@
      */
     public void testRetrievingSecurityLogsThrowsSecurityException() {
         try {
-            mDevicePolicyManager.retrieveSecurityLogs(getWho());
+            mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT);
             fail("did not throw expected SecurityException");
         } catch (SecurityException expected) {
         }
@@ -220,7 +227,7 @@
      */
     public void testRetrievingPreviousSecurityLogsThrowsSecurityException() {
         try {
-            mDevicePolicyManager.retrievePreRebootSecurityLogs(getWho());
+            mDevicePolicyManager.retrievePreRebootSecurityLogs(ADMIN_RECEIVER_COMPONENT);
             fail("did not throw expected SecurityException");
         } catch (SecurityException expected) {
         }
@@ -236,6 +243,10 @@
         verifyKeystoreEventsPresent(events);
         verifyKeyChainEventsPresent(events);
         verifyAdminEventsPresent(events);
+        verifyAdbShellCommand(events); // Event generated from host side logic
+        if (mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+            verifyEventsRedacted(events);
+        }
     }
 
     private void verifyAutomaticEventsPresent(List<SecurityEvent> events) {
@@ -264,6 +275,39 @@
         verifyUserRestrictionEventsPresent(events);
         verifyCameraPolicyEvents(events);
     }
+    private void verifyAdbShellCommand(List<SecurityEvent> events) {
+        // Won't be able to locate the command on org-owned devices, as it will be redacted.
+        if (!mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+            findEvent("adb command", events,
+                    e -> e.getTag() == TAG_ADB_SHELL_CMD &&
+                            e.getData().equals("whoami"));
+
+        }
+    }
+
+    private void verifyEventsRedacted(List<SecurityEvent> events) {
+        final int userId = Process.myUserHandle().getIdentifier();
+        for (SecurityEvent event : events) {
+            switch (event.getTag()) {
+                case TAG_ADB_SHELL_CMD:
+                    assertTrue(TextUtils.isEmpty((String) event.getData()));
+                    break;
+                case TAG_APP_PROCESS_START:
+                case TAG_KEY_GENERATED:
+                case TAG_KEY_IMPORT:
+                case TAG_KEY_DESTRUCTION:
+                    assertEquals(userId, UserHandle.getUserId(getInt(event, UID_INDEX)));
+                    break;
+                case TAG_CERT_AUTHORITY_INSTALLED:
+                case TAG_CERT_AUTHORITY_REMOVED:
+                    assertEquals(userId, getInt(event, USERID_INDEX));
+                    break;
+                case TAG_KEY_INTEGRITY_VIOLATION:
+                    assertEquals(userId, UserHandle.getUserId(getInt(event, 1)));
+                    break;
+            }
+        }
+    }
 
     /**
      * Generates events for positive test cases.
@@ -303,15 +347,26 @@
         // Retry once after seeping for 1 second, in case "dpm force-security-logs" hasn't taken
         // effect just yet.
         for (int i = 0; i < 2 && events == null; i++) {
-            events = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+            events = mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT);
             if (events == null) Thread.sleep(1000);
         }
-
-        verifySecurityLogs(events);
+        try {
+            verifySecurityLogs(events);
+        } catch (AssertionFailedError e) {
+            dumpSecurityLogs(events);
+            throw e;
+        }
 
         return events;
     }
 
+    private void dumpSecurityLogs(List<SecurityEvent> events) {
+        Log.d(TAG, "Security events dump:");
+        for (SecurityEvent event : events) {
+            Log.d(TAG, event.toString());
+        }
+    }
+
     /**
      * Test: check that there are no gaps between ids in two consecutive batches. Shared preference
      * is used to store these numbers between test invocations.
@@ -470,9 +525,9 @@
      * security logging is enabled after its execution.
      */
     public void testEnablingSecurityLogging() {
-        assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
-        mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), true);
-        assertTrue(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+        assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
+        mDevicePolicyManager.setSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT, true);
+        assertTrue(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
     }
 
     /**
@@ -480,11 +535,11 @@
      * disabled after its execution.
      */
     public void testDisablingSecurityLogging() {
-        mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), false);
-        assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+        mDevicePolicyManager.setSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT, false);
+        assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
 
         // Verify that logs are actually not available.
-        assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+        assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
     }
 
     /**
@@ -492,11 +547,12 @@
      * null.
      */
     public void testSecurityLoggingRetrievalRateLimited() {
-        final List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+        final List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(
+                ADMIN_RECEIVER_COMPONENT);
         // if logs is null it means that that attempt was rate limited => test PASS
         if (logs != null) {
-            assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
-            assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+            assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
+            assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
         }
     }
 
@@ -546,7 +602,8 @@
     }
 
     private void installCaCert() {
-        mDevicePolicyManager.installCaCert(getWho(), TEST_CA.getBytes());
+        assertTrue(
+                mDevicePolicyManager.installCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes()));
     }
 
     private void verifyCertInstalledEventPresent(List<SecurityEvent> events) {
@@ -557,7 +614,7 @@
     }
 
     private void uninstallCaCert() {
-        mDevicePolicyManager.uninstallCaCert(getWho(), TEST_CA.getBytes());
+        mDevicePolicyManager.uninstallCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes());
     }
 
     private void verifyCertUninstalledEventPresent(List<SecurityEvent> events) {
@@ -568,21 +625,21 @@
     }
 
     private void generatePasswordComplexityEvents() {
-        mDevicePolicyManager.setPasswordQuality(getWho(), PASSWORD_QUALITY_COMPLEX);
-        mDevicePolicyManager.setPasswordMinimumLength(getWho(), TEST_PWD_LENGTH);
-        mDevicePolicyManager.setPasswordMinimumLetters(getWho(), TEST_PWD_CHARS);
-        mDevicePolicyManager.setPasswordMinimumNonLetter(getWho(), TEST_PWD_CHARS);
-        mDevicePolicyManager.setPasswordMinimumUpperCase(getWho(), TEST_PWD_CHARS);
-        mDevicePolicyManager.setPasswordMinimumLowerCase(getWho(), TEST_PWD_CHARS);
-        mDevicePolicyManager.setPasswordMinimumNumeric(getWho(), TEST_PWD_CHARS);
-        mDevicePolicyManager.setPasswordMinimumSymbols(getWho(), TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
+        mDevicePolicyManager.setPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT, TEST_PWD_LENGTH);
+        mDevicePolicyManager.setPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+        mDevicePolicyManager.setPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
     }
 
     private void verifyPasswordComplexityEventsPresent(List<SecurityEvent> events) {
         final int userId = Process.myUserHandle().getIdentifier();
         // This reflects default values for password complexity event payload fields.
         final Object[] expectedPayload = new Object[] {
-                getWho().getPackageName(), // admin package
+                ADMIN_RECEIVER_COMPONENT.getPackageName(), // admin package
                 userId,                    // admin user
                 userId,                    // target user
                 0,                         // default password length
@@ -617,37 +674,40 @@
 
     private void generateLockingPolicyEvents() {
         if (mHasSecureLockScreen) {
-            mDevicePolicyManager.setPasswordExpirationTimeout(getWho(),
+            mDevicePolicyManager.setPasswordExpirationTimeout(ADMIN_RECEIVER_COMPONENT,
                     TEST_PWD_EXPIRATION_TIMEOUT);
-            mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
-            mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+            mDevicePolicyManager.setPasswordHistoryLength(ADMIN_RECEIVER_COMPONENT,
+                    TEST_PWD_HISTORY_LENGTH);
+            mDevicePolicyManager.setMaximumFailedPasswordsForWipe(ADMIN_RECEIVER_COMPONENT,
+                    TEST_PWD_MAX_ATTEMPTS);
         }
-        mDevicePolicyManager.setKeyguardDisabledFeatures(getWho(), KEYGUARD_DISABLE_FINGERPRINT);
-        mDevicePolicyManager.setMaximumTimeToLock(getWho(), TEST_MAX_TIME_TO_LOCK);
+        mDevicePolicyManager.setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+                KEYGUARD_DISABLE_FINGERPRINT);
+        mDevicePolicyManager.setMaximumTimeToLock(ADMIN_RECEIVER_COMPONENT, TEST_MAX_TIME_TO_LOCK);
         mDevicePolicyManager.lockNow();
     }
 
     private void verifyLockingPolicyEventsPresent(List<SecurityEvent> events) {
         final int userId = Process.myUserHandle().getIdentifier();
-
+        final String packageName = ADMIN_RECEIVER_COMPONENT.getPackageName();
         if (mHasSecureLockScreen) {
             findEvent("set password expiration", events,
                     e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
-                            getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                            getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                             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()) &&
+                            getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                             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()) &&
+                            getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                             getInt(e, ADMIN_USER_INDEX) == userId &&
                             getInt(e, TARGET_USER_INDEX) == userId &&
                             getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
@@ -655,21 +715,21 @@
 
         findEvent("set keyguard disabled features", events,
                 e -> e.getTag() == TAG_KEYGUARD_DISABLED_FEATURES_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                         getInt(e, ADMIN_USER_INDEX) == userId &&
                         getInt(e, TARGET_USER_INDEX) == userId &&
                         getInt(e, KEYGUARD_FEATURES_INDEX) == KEYGUARD_DISABLE_FINGERPRINT);
 
         findEvent("set screen lock timeout", events,
                 e -> e.getTag() == TAG_MAX_SCREEN_LOCK_TIMEOUT_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                         getInt(e, ADMIN_USER_INDEX) == userId &&
                         getInt(e, TARGET_USER_INDEX) == userId &&
                         getLong(e, MAX_SCREEN_TIMEOUT_INDEX) == TEST_MAX_TIME_TO_LOCK);
 
         findEvent("set screen lock timeout", events,
                 e -> e.getTag() == TAG_REMOTE_LOCK &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
                         getInt(e, ADMIN_USER_INDEX) == userId);
     }
 
@@ -681,8 +741,10 @@
     }
 
     private void generateUserRestrictionEvents() {
-        mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_FUN);
-        mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_FUN);
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_PRINTING);
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_PRINTING);
     }
 
     private void verifyUserRestrictionEventsPresent(List<SecurityEvent> events) {
@@ -694,14 +756,15 @@
         final int userId = Process.myUserHandle().getIdentifier();
         findEvent(description, events,
                 e -> e.getTag() == tag &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(
+                                ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
                         getInt(e, ADMIN_USER_INDEX) == userId &&
-                        UserManager.DISALLOW_FUN.equals(getString(e, USER_RESTRICTION_INDEX)));
+                        UserManager.DISALLOW_PRINTING.equals(getString(e, USER_RESTRICTION_INDEX)));
     }
 
     private void generateCameraPolicyEvents() {
-        mDevicePolicyManager.setCameraDisabled(getWho(), true);
-        mDevicePolicyManager.setCameraDisabled(getWho(), false);
+        mDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, true);
+        mDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, false);
     }
 
     private void verifyCameraPolicyEvents(List<SecurityEvent> events) {
@@ -709,14 +772,16 @@
 
         findEvent("set camera disabled", events,
                 e -> e.getTag() == TAG_CAMERA_POLICY_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(
+                                ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
                         getInt(e, ADMIN_USER_INDEX) == userId &&
                         getInt(e, TARGET_USER_INDEX) == userId &&
                         getInt(e, CAMERA_DISABLED_INDEX) == 1);
 
         findEvent("set camera enabled", events,
                 e -> e.getTag() == TAG_CAMERA_POLICY_SET &&
-                        getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+                        getString(e, ADMIN_PKG_INDEX).equals(
+                                ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
                         getInt(e, ADMIN_USER_INDEX) == userId &&
                         getInt(e, TARGET_USER_INDEX) == userId &&
                         getInt(e, CAMERA_DISABLED_INDEX) == 0);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 3878d10..8fd637b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -24,22 +24,12 @@
 import static org.junit.Assert.fail;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
 import com.android.tradefed.config.Option;
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.TarUtil;
 
 import com.google.common.io.ByteStreams;
 
@@ -62,6 +52,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -75,7 +66,7 @@
 public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
 
     //The maximum time to wait for user to be unlocked.
-    private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
+    private static final long USER_UNLOCK_TIMEOUT_SEC = 30;
     private static final String USER_STATE_UNLOCKED = "RUNNING_UNLOCKED";
     @Option(
             name = "skip-device-admin-feature-check",
@@ -179,6 +170,7 @@
     @Before
     public void setUp() throws Exception {
         assertNotNull(getBuild());  // ensure build has been set before test is run.
+        ensurePackageManagerReady();
         mHasFeature = getDevice().getApiLevel() >= 21; /* Build.VERSION_CODES.L */
         if (!mSkipDeviceAdminFeatureCheck) {
             mHasFeature = mHasFeature && hasDeviceFeature("android.software.device_admin");
@@ -230,16 +222,27 @@
         executeShellCommand("input keyevent KEYCODE_HOME");
     }
 
-    void waitForUserUnlock(int userId) throws Exception {
-        final String command = String.format("am get-started-user-state %d", userId);
-        final long deadline = System.nanoTime() + USER_UNLOCK_TIMEOUT_NANO;
-        while (System.nanoTime() <= deadline) {
-            if (getDevice().executeShellCommand(command).startsWith(USER_STATE_UNLOCKED)) {
-                return;
+    /** If package manager is not available, e.g. after system crash, wait for it a little bit. */
+    private void ensurePackageManagerReady() throws Exception {
+        waitForOutput("Package manager didn't become available", "service check package",
+                s -> s.trim().equals("Service package: found"), 120 /* seconds */);
+    }
+
+    protected void waitForUserUnlock(int userId) throws Exception {
+        waitForOutput("User is not unlocked.",
+                String.format("am get-started-user-state %d", userId),
+                s -> s.startsWith(USER_STATE_UNLOCKED), USER_UNLOCK_TIMEOUT_SEC);
+    }
+
+    protected void waitForOutput(String message, String command, Predicate<String> predicate,
+            long timeoutSec) throws Exception {
+        final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSec);
+        while (!predicate.test(getDevice().executeShellCommand(command))) {
+            if (System.nanoTime() > deadline) {
+                fail(message);
             }
-            Thread.sleep(100);
+            Thread.sleep(1000);
         }
-        fail("User is not unlocked.");
     }
 
     @After
@@ -1000,4 +1003,15 @@
         getDevice().pushFile(file, TEST_UPDATE_LOCATION + "/" + fileName);
         file.delete();
     }
+
+    boolean hasService(String service) {
+        String command = "service check " + service;
+        try {
+            String commandOutput = getDevice().executeShellCommand(command);
+            return !commandOutput.contains("not found");
+        } catch (Exception e) {
+            CLog.w("Exception running '" + command + "': " + e);
+            return false;
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 3a41d0f..09c05aa 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -2095,6 +2095,11 @@
         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId);
     }
 
+    protected void executeDeviceTestMethod(String className, String testName,
+            Map<String, String> params) throws Exception {
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId, params);
+    }
+
     private void installAppPermissionAppAsUser()
             throws FileNotFoundException, DeviceNotAvailableException {
         installAppAsUser(PERMISSIONS_APP_APK, false, mUserId);
@@ -2312,19 +2317,4 @@
         getDevice().executeShellCommand(
                 restricted ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
     }
-
-    // TODO: copied from RequiredServiceRule, which is on compatibility-device-util
-    // (and we use compatibility-host-util)
-    public boolean hasService(String service) {
-        // TODO: ideally should call SystemServiceManager directly, but we would need to open
-        // some @Testing APIs for that.
-        String command = "service check " + service;
-        try {
-            String commandOutput = getDevice().executeShellCommand(command);
-            return !commandOutput.contains("not found");
-        } catch (Exception e) {
-            CLog.w("Exception running '" + command + "': " + e);
-            return false;
-        }
-    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index cdf5bd9..e45e647 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -78,9 +78,6 @@
     private static final String TEST_APP_PKG = "android.packageinstaller.emptytestapp.cts";
     private static final String TEST_APP_LOCATION = "/data/local/tmp/cts/packageinstaller/";
 
-    private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
-    private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
-
     private static final String ARG_NETWORK_LOGGING_BATCH_COUNT = "batchCount";
 
     private static final String LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK =
@@ -456,97 +453,6 @@
     }
 
     @Test
-    public void testSecurityLoggingWithTwoUsers() throws Exception {
-        if (!mHasFeature || !canCreateAdditionalUsers(1)) {
-            return;
-        }
-
-        final int userId = createUser();
-        try {
-            // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs
-            // should throw security exception.
-            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
-            executeDeviceTestMethod(".SecurityLoggingTest",
-                    "testRetrievingSecurityLogsThrowsSecurityException");
-            executeDeviceTestMethod(".SecurityLoggingTest",
-                    "testRetrievingPreviousSecurityLogsThrowsSecurityException");
-        } finally {
-            removeUser(userId);
-            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
-        }
-    }
-
-    @FlakyTest(bugId = 137093665)
-    @Test
-    public void testSecurityLoggingWithSingleUser() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        // Backup stay awake setting because testGenerateLogs() will turn it off.
-        final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
-        try {
-            // Turn logging on.
-            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
-            // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
-            rebootAndWaitUntilReady();
-
-            // Generate various types of events on device side and check that they are logged.
-            executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs");
-            getDevice().executeShellCommand("dpm force-security-logs");
-            executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs");
-
-            // Reboot the device, so the security event ids are reset.
-            rebootAndWaitUntilReady();
-
-            // Verify event ids are consistent across a consecutive batch.
-            for (int batchNumber = 0; batchNumber < 3; batchNumber++) {
-                generateDummySecurityLogs();
-                getDevice().executeShellCommand("dpm force-security-logs");
-                executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds",
-                        Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER,
-                                Integer.toString(batchNumber)));
-            }
-
-            // Immediately attempting to fetch events again should fail.
-            executeDeviceTestMethod(".SecurityLoggingTest",
-                    "testSecurityLoggingRetrievalRateLimited");
-            // Turn logging off.
-            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
-        } finally {
-            // Restore stay awake setting.
-            if (stayAwake != null) {
-                getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
-            }
-        }
-    }
-
-    @Test
-    public void testSecurityLoggingEnabledLogged() throws Exception {
-        if (!mHasFeature || !isStatsdEnabled(getDevice())) {
-            return;
-        }
-        assertMetricsLogged(getDevice(), () -> {
-            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
-            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
-        }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
-                .setAdminPackageName(DEVICE_OWNER_PKG)
-                .setBoolean(true)
-                .build(),
-            new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
-                    .setAdminPackageName(DEVICE_OWNER_PKG)
-                    .setBoolean(false)
-                    .build());
-
-    }
-
-    private void generateDummySecurityLogs() throws DeviceNotAvailableException {
-        // Trigger security events of type TAG_ADB_SHELL_CMD.
-        for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
-            getDevice().executeShellCommand("echo just_testing_" + i);
-        }
-    }
-
-    @Test
     public void testNetworkLoggingWithTwoUsers() throws Exception {
         if (!mHasFeature || !canCreateAdditionalUsers(1)) {
             return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index d28ecd9..794cb06 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -37,6 +37,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -49,6 +50,9 @@
 
     private static final String DELEGATION_NETWORK_LOGGING = "delegation-network-logging";
 
+    private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
+    private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
@@ -302,6 +306,97 @@
                     .build());
     }
 
+    @FlakyTest(bugId = 137093665)
+    @Test
+    public void testSecurityLoggingWithSingleUser() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Backup stay awake setting because testGenerateLogs() will turn it off.
+        final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
+        try {
+            // Turn logging on.
+            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+            // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
+            rebootAndWaitUntilReady();
+            waitForUserUnlock(mUserId);
+
+            // Generate various types of events on device side and check that they are logged.
+            executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs");
+            getDevice().executeShellCommand("whoami"); // Generate adb command securty event
+            getDevice().executeShellCommand("dpm force-security-logs");
+            executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs");
+
+            // Reboot the device, so the security event ids are reset.
+            rebootAndWaitUntilReady();
+
+            // Verify event ids are consistent across a consecutive batch.
+            for (int batchNumber = 0; batchNumber < 3; batchNumber++) {
+                generateDummySecurityLogs();
+                getDevice().executeShellCommand("dpm force-security-logs");
+                executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds",
+                        Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER,
+                                Integer.toString(batchNumber)));
+            }
+
+            // Immediately attempting to fetch events again should fail.
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testSecurityLoggingRetrievalRateLimited");
+        } finally {
+            // Turn logging off.
+            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+            // Restore stay awake setting.
+            if (stayAwake != null) {
+                getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
+            }
+        }
+    }
+
+    @Test
+    public void testSecurityLoggingEnabledLogged() throws Exception {
+        if (!mHasFeature || !isStatsdEnabled(getDevice())) {
+            return;
+        }
+        assertMetricsLogged(getDevice(), () -> {
+            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+        }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
+                .setAdminPackageName(DEVICE_ADMIN_PKG)
+                .setBoolean(true)
+                .build(),
+            new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
+                    .setAdminPackageName(DEVICE_ADMIN_PKG)
+                    .setBoolean(false)
+                    .build());
+    }
+
+    @Test
+    public void testSecurityLoggingWithTwoUsers() throws Exception {
+        if (!mHasFeature || !canCreateAdditionalUsers(1)) {
+            return;
+        }
+
+        final int userId = createUser();
+        try {
+            // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs
+            // should throw security exception.
+            executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testRetrievingSecurityLogsThrowsSecurityException");
+            executeDeviceTestMethod(".SecurityLoggingTest",
+                    "testRetrievingPreviousSecurityLogsThrowsSecurityException");
+        } finally {
+            removeUser(userId);
+            executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+        }
+    }
+
+    private void generateDummySecurityLogs() throws Exception {
+        // Trigger security events of type TAG_ADB_SHELL_CMD.
+        for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
+            getDevice().executeShellCommand("echo just_testing_" + i);
+        }
+    }
     private int createSecondaryUserAsProfileOwner() throws Exception {
         final int userId = createUser();
         installAppAsUser(INTENT_RECEIVER_APK, userId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index 4078c12..5716258 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -31,13 +31,10 @@
 
 import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
 
 import org.junit.Ignore;
 import org.junit.Test;
 
-import java.util.concurrent.TimeUnit;
-
 /**
  * Tests for organization-owned Profile Owner.
  */
@@ -273,6 +270,44 @@
                         .build());
     }
 
+    @FlakyTest(bugId = 137093665)
+    @Test
+    public void testSecurityLogging() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Backup stay awake setting because testGenerateLogs() will turn it off.
+        final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
+        try {
+            // Turn logging on.
+            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+                    "testEnablingSecurityLogging", mUserId);
+            // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
+            rebootAndWaitUntilReady();
+            waitForUserUnlock(mUserId);
+
+            // Generate various types of events on device side and check that they are logged.
+            runDeviceTestsAsUser(DEVICE_ADMIN_PKG,".SecurityLoggingTest",
+                    "testGenerateLogs", mUserId);
+            getDevice().executeShellCommand("whoami"); // Generate adb command securty event
+            getDevice().executeShellCommand("dpm force-security-logs");
+            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+                    "testVerifyGeneratedLogs", mUserId);
+
+            // Immediately attempting to fetch events again should fail.
+            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+                    "testSecurityLoggingRetrievalRateLimited", mUserId);
+        } finally {
+            // Turn logging off.
+            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+                    "testDisablingSecurityLogging", mUserId);
+            // Restore stay awake setting.
+            if (stayAwake != null) {
+                getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
+            }
+        }
+    }
+
     private void failToCreateUser() throws Exception {
         String command ="pm create-user " + "TestUser_" + System.currentTimeMillis();
         String commandOutput = getDevice().executeShellCommand(command);
@@ -282,25 +317,6 @@
         assertEquals("Error:", tokens[0]);
     }
 
-    protected int createUser() throws Exception {
-        String command ="pm create-user " + "TestUser_" + System.currentTimeMillis();
-        String commandOutput = getDevice().executeShellCommand(command);
-
-        String[] tokens = commandOutput.split("\\s+");
-        assertTrue(tokens.length > 0);
-        assertEquals("Success:", tokens[0]);
-        int userId = Integer.parseInt(tokens[tokens.length-1]);
-        startUser(userId);
-        return userId;
-    }
-
-    protected void removeUser(int userId) throws Exception  {
-        if (listUsers().contains(userId) && userId != USER_SYSTEM) {
-            String command = "am stop-user -w -f " + userId;
-            getDevice().executeShellCommand(command);
-        }
-    }
-
     @Test
     public void testSetTime() throws Exception {
         if (!mHasFeature) {
@@ -397,7 +413,7 @@
     }
 
     @Test
-    public void testApplicationHidden() throws Exception {
+    public void testApplicationHiddenParent() throws Exception {
         if (!mHasFeature) {
             return;
         }
@@ -476,22 +492,16 @@
         }
     }
 
-    private void setupIme(int userId, String imeApk, String imePackage) throws Exception {
+    private void setupIme(int userId, String imeApk, String imeComponent) throws Exception {
         installAppAsUser(imeApk, userId);
-        // Wait until IMS service is registered by the system.
-        final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(5);
-        while (true) {
-            final String availableImes = getDevice().executeShellCommand(
-                    String.format("ime list --user %d -s -a", userId));
-            if (availableImes.contains(imePackage)) {
-                break;
-            }
-            assertTrue("Failed waiting for IME to become available", System.nanoTime() < deadline);
-            Thread.sleep(100);
-        }
 
-        executeShellCommand("ime enable " + imePackage);
-        executeShellCommand("ime set " + imePackage);
+        // Wait until IMS service is registered by the system.
+        waitForOutput("Failed waiting for IME to become available",
+                String.format("ime list --user %d -s -a", userId),
+                s -> s.contains(imeComponent), 10 /* seconds */);
+
+        executeShellCommand("ime enable " + imeComponent);
+        executeShellCommand("ime set " + imeComponent);
     }
 
 
@@ -532,17 +542,6 @@
                         userId, /* expectFailure */ false));
     }
 
-    private boolean hasService(String service) {
-        String command = "service check " + service;
-        try {
-            String commandOutput = getDevice().executeShellCommand(command);
-            return !commandOutput.contains("not found");
-        } catch (Exception e) {
-            LogUtil.CLog.w("Exception running '" + command + "': " + e);
-            return false;
-        }
-    }
-
     @Test
     public void testSetPersonalAppsSuspendedLogged() throws Exception {
         if (!mHasFeature|| !isStatsdEnabled(getDevice())) {
diff --git a/hostsidetests/net/AndroidTest.xml b/hostsidetests/net/AndroidTest.xml
index 0452fc6..7cc0dd1 100644
--- a/hostsidetests/net/AndroidTest.xml
+++ b/hostsidetests/net/AndroidTest.xml
@@ -25,6 +25,7 @@
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="teardown-command" value="cmd power set-mode 0" />
         <option name="teardown-command" value="cmd battery reset" />
+        <option name="teardown-command" value="cmd netpolicy stop-watching" />
     </target_preparer>
 
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 529b640..69dd2ad 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -79,7 +79,6 @@
     private static final String TEST_APP2_SERVICE_CLASS = TEST_APP2_PKG + ".MyForegroundService";
 
     private static final int SLEEP_TIME_SEC = 1;
-    private static final boolean DEBUG = true;
 
     // Constants below must match values defined on app2's Common.java
     private static final String MANIFEST_RECEIVER = "ManifestReceiver";
@@ -159,6 +158,7 @@
         if (!mIsLocationOn) {
             enableLocation();
         }
+        executeShellCommand("cmd netpolicy start-watching " + mUid);
         setAppIdle(false);
 
         Log.i(TAG, "Apps status:\n"
@@ -167,6 +167,7 @@
     }
 
     protected void tearDown() throws Exception {
+        executeShellCommand("cmd netpolicy stop-watching");
         if (!mIsLocationOn) {
             disableLocation();
         }
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index fc1b57e..9c55177 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -42,6 +42,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraManager;
+import android.location.GnssStatus;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
@@ -270,6 +271,81 @@
     }
 
     @Test
+    public void testGpsStatus() {
+        Context context = InstrumentationRegistry.getContext();
+        final LocationManager locManager = context.getSystemService(LocationManager.class);
+
+        if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+            Log.e(TAG, "GPS provider is not enabled");
+            return;
+        }
+
+        // Time out set to 85 seconds (5 seconds for sleep and a possible 85 seconds if TTFF takes
+        // max time which would be around 90 seconds.
+        // This is based on similar location cts test timeout values.
+        final int TIMEOUT_IN_MSEC = 85_000;
+        final int SLEEP_TIME_IN_MSEC = 5_000;
+        // TTFF could take up to 90 seconds, thus we need to wait till TTFF does occur if it does
+        // not occur in the first SLEEP_TIME_IN_MSEC
+        final CountDownLatch mLatchTtff = new CountDownLatch(1);
+
+        GnssStatus.Callback gnssStatusCallback = new GnssStatus.Callback() {
+            @Override
+            public void onStarted() {
+                Log.v(TAG, "Gnss Status Listener Started");
+            }
+
+            @Override
+            public void onStopped() {
+                Log.v(TAG, "Gnss Status Listener Stopped");
+            }
+
+            @Override
+            public void onFirstFix(int ttffMillis) {
+                Log.v(TAG, "Gnss Status Listener Received TTFF");
+                mLatchTtff.countDown();
+            }
+
+            @Override
+            public void onSatelliteStatusChanged(GnssStatus status) {
+                Log.v(TAG, "Gnss Status Listener Received Status Update");
+            }
+        };
+
+        boolean gnssStatusCallbackAdded = locManager.registerGnssStatusCallback(
+                gnssStatusCallback, new Handler(Looper.getMainLooper()));
+        if (!gnssStatusCallbackAdded) {
+            // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
+            Log.e(TAG, "Failed to start gnss status callback");
+        }
+
+        final LocationListener locListener = new LocationListener() {
+            public void onLocationChanged(Location location) {
+                Log.v(TAG, "onLocationChanged: location has been obtained");
+            }
+            public void onProviderDisabled(String provider) {
+                Log.v(TAG, "onProviderDisabled " + provider);
+            }
+            public void onProviderEnabled(String provider) {
+                Log.v(TAG, "onProviderEnabled " + provider);
+            }
+            public void onStatusChanged(String provider, int status, Bundle extras) {
+                Log.v(TAG, "onStatusChanged " + provider + " " + status);
+            }
+        };
+
+        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+                0,
+                0 /* minDistance */,
+                locListener,
+                Looper.getMainLooper());
+        sleep(SLEEP_TIME_IN_MSEC);
+        waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchTtff, null);
+        locManager.removeUpdates(locListener);
+        locManager.unregisterGnssStatusCallback(gnssStatusCallback);
+    }
+
+    @Test
     public void testScreenBrightness() {
         Context context = InstrumentationRegistry.getContext();
         PowerManager pm = context.getSystemService(PowerManager.class);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index d94316d8..1d4b2d6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -583,6 +583,69 @@
         }
     }
 
+    public void testGnssStats() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+
+        // Get GnssMetrics as a simple gauge metric.
+        StatsdConfig.Builder config = getPulledConfig();
+        addGaugeAtomWithDimensions(config, Atom.GNSS_STATS_FIELD_NUMBER, null);
+        uploadConfig(config);
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
+        // Whitelist this app against background location request throttling
+        String origWhitelist = getDevice().executeShellCommand(
+                "settings get global location_background_throttle_package_whitelist").trim();
+        getDevice().executeShellCommand(String.format(
+                "settings put global location_background_throttle_package_whitelist %s",
+                DEVICE_SIDE_TEST_PACKAGE));
+
+        try {
+            runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGpsStatus");
+
+            Thread.sleep(WAIT_TIME_LONG);
+            // Trigger a pull and wait for new pull before killing the process.
+            setAppBreadcrumbPredicate();
+            Thread.sleep(WAIT_TIME_LONG);
+
+            // Assert about GnssMetrics for the test app.
+            List<Atom> atoms = getGaugeMetricDataList();
+
+            boolean found = false;
+            for (Atom atom : atoms) {
+                AtomsProto.GnssStats state = atom.getGnssStats();
+                found = true;
+                assertThat(state.getLocationReports()).isGreaterThan((long) 0);
+                assertThat(state.getLocationFailureReports()).isAtLeast((long) 0);
+                assertThat(state.getTimeToFirstFixReports()).isGreaterThan((long) 0);
+                assertThat(state.getTimeToFirstFixMilliS()).isGreaterThan((long) 0);
+                assertThat(state.getPositionAccuracyReports()).isGreaterThan((long) 0);
+                assertThat(state.getPositionAccuracyMeters()).isGreaterThan((long) 0);
+                assertThat(state.getTopFourAverageCn0Reports()).isGreaterThan((long) 0);
+                assertThat(state.getTopFourAverageCn0DbMhz()).isGreaterThan((long) 0);
+                assertThat(state.getL5TopFourAverageCn0Reports()).isAtLeast((long) 0);
+                assertThat(state.getL5TopFourAverageCn0DbMhz()).isAtLeast((long) 0);
+                assertThat(state.getSvStatusReports()).isGreaterThan((long) 0);
+                assertThat(state.getSvStatusReportsUsedInFix()).isGreaterThan((long) 0);
+                assertThat(state.getL5SvStatusReports()).isAtLeast((long) 0);
+                assertThat(state.getL5SvStatusReportsUsedInFix()).isAtLeast((long) 0);
+            }
+            assertWithMessage(String.format("Did not find a matching atom"))
+                    .that(found).isTrue();
+        } finally {
+            if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
+                getDevice().executeShellCommand(
+                        "settings delete global location_background_throttle_package_whitelist");
+            } else {
+                getDevice().executeShellCommand(String.format(
+                        "settings put global location_background_throttle_package_whitelist %s",
+                        origWhitelist));
+            }
+        }
+    }
+
     public void testMediaCodecActivity() throws Exception {
         if (statsdDisabled()) {
             return;
diff --git a/tests/BlobStore/Android.bp b/tests/BlobStore/Android.bp
index c168eb6..0d51b2d 100644
--- a/tests/BlobStore/Android.bp
+++ b/tests/BlobStore/Android.bp
@@ -25,11 +25,35 @@
     ],
     srcs: [
         "src/**/*.java",
+        ":CtsBlobStoreTestsAidl",
     ],
     test_suites: [
         "cts",
         "vts",
         "general-tests",
     ],
-    platform_apis: true,
+    sdk_version: "test_current"
+}
+
+android_test_helper_app {
+    name: "CtsBlobStoreTestHelper",
+    defaults: ["cts_defaults"],
+    srcs: [
+        "helper-app/src/**/*.java",
+        ":CtsBlobStoreTestsAidl"
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    manifest: "helper-app/AndroidManifest.xml",
+    sdk_version: "test_current"
+}
+
+filegroup {
+    name: "CtsBlobStoreTestsAidl",
+    srcs: [
+        "aidl/**/*.aidl",
+    ]
 }
\ No newline at end of file
diff --git a/tests/BlobStore/AndroidTest.xml b/tests/BlobStore/AndroidTest.xml
index 98b9d86..42c6a67 100644
--- a/tests/BlobStore/AndroidTest.xml
+++ b/tests/BlobStore/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="CtsBlobStoreTestCases.apk" />
+        <option name="test-file-name" value="CtsBlobStoreTestHelper.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.cts.blob" />
diff --git a/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl b/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl
new file mode 100644
index 0000000..86d2f18
--- /dev/null
+++ b/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.blob;
+
+import android.app.blob.BlobHandle;
+import android.app.usage.StorageStats;
+
+interface ICommandReceiver {
+    void acquireLease(in BlobHandle blobHandle);
+    void releaseLease(in BlobHandle blobHandle);
+
+    StorageStats queryStatsForPackage();
+    StorageStats queryStatsForUid();
+}
\ No newline at end of file
diff --git a/tests/BlobStore/helper-app/AndroidManifest.xml b/tests/BlobStore/helper-app/AndroidManifest.xml
new file mode 100644
index 0000000..5ad854f
--- /dev/null
+++ b/tests/BlobStore/helper-app/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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.blob.helper" >
+
+    <application>
+        <service android:name=".BlobStoreTestService" android:exported="true"/>
+    </application>
+
+</manifest>
+
diff --git a/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
new file mode 100644
index 0000000..4694dc5
--- /dev/null
+++ b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.blob.helper;
+
+import static android.os.storage.StorageManager.UUID_DEFAULT;
+
+import android.app.Service;
+import android.app.blob.BlobHandle;
+import android.app.blob.BlobStoreManager;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.IBinder;
+import android.os.Process;
+
+import com.android.cts.blob.ICommandReceiver;
+
+import java.io.IOException;
+
+public class BlobStoreTestService extends Service {
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new CommandReceiver();
+    }
+
+    private class CommandReceiver extends ICommandReceiver.Stub {
+        public void acquireLease(BlobHandle blobHandle) {
+            final BlobStoreManager blobStoreManager = getSystemService(
+                    BlobStoreManager.class);
+            try {
+                blobStoreManager.acquireLease(blobHandle, "Test description");
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public void releaseLease(BlobHandle blobHandle) {
+            final BlobStoreManager blobStoreManager = getSystemService(
+                    BlobStoreManager.class);
+            try {
+                blobStoreManager.releaseLease(blobHandle);
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public StorageStats queryStatsForPackage() {
+            final StorageStatsManager storageStatsManager = getSystemService(
+                    StorageStatsManager.class);
+            try {
+                return storageStatsManager
+                        .queryStatsForPackage(UUID_DEFAULT, getPackageName(), getUser());
+            } catch (IOException | NameNotFoundException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public StorageStats queryStatsForUid() {
+            final StorageStatsManager storageStatsManager = getSystemService(
+                    StorageStatsManager.class);
+            try {
+                return storageStatsManager
+                        .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+}
diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index ab76368..853f7ce 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -15,16 +15,29 @@
  */
 package com.android.cts.blob;
 
+import static android.os.storage.StorageManager.UUID_DEFAULT;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.testng.Assert.assertThrows;
 
 import android.app.blob.BlobHandle;
 import android.app.blob.BlobStoreManager;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.util.Log;
 
 import com.android.cts.blob.R;
+import com.android.cts.blob.ICommandReceiver;
 import com.android.utils.blob.DummyBlobData;
 
 import org.junit.After;
@@ -34,7 +47,9 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -42,8 +57,15 @@
 
 @RunWith(AndroidJUnit4.class)
 public class BlobStoreManagerTest {
+    private static final String TAG = "BlobStoreTest";
+
     private static final long TIMEOUT_COMMIT_CALLBACK_SEC = 5;
 
+    private static final long TIMEOUT_BIND_SERVICE_SEC = 2;
+
+    private static final String HELPER_PKG = "com.android.cts.blob.helper";
+    private static final String HELPER_SERVICE = HELPER_PKG + ".BlobStoreTestService";
+
     private Context mContext;
     private BlobStoreManager mBlobStoreManager;
 
@@ -56,18 +78,17 @@
         mContext = InstrumentationRegistry.getInstrumentation().getContext();
         mBlobStoreManager = (BlobStoreManager) mContext.getSystemService(
                 Context.BLOB_STORE_SERVICE);
-        mCreatedSessionIds.clear();
+        clearAllBlobsData();
     }
 
     @After
     public void tearDown() {
-        for (long sessionId : mCreatedSessionIds) {
-            try {
-                mBlobStoreManager.deleteSession(sessionId);
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
+        clearAllBlobsData();
+    }
+
+    private void clearAllBlobsData() {
+        executeCmd("cmd blob_store clear-all-sessions");
+        executeCmd("cmd blob_store clear-all-blobs");
     }
 
     @Test
@@ -443,9 +464,199 @@
         assertThrows(NullPointerException.class, () -> mBlobStoreManager.releaseLease(null));
     }
 
+    @Test
+    public void testStorageAttributedToSelf() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData(mContext);
+        blobData.prepare();
+        final long partialFileSize = 3373L;
+
+        final StorageStatsManager storageStatsManager = mContext.getSystemService(
+                StorageStatsManager.class);
+        StorageStats beforeStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats beforeStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // Create a session and write some data.
+        final long sessionId = createSession(blobData.getBlobHandle());
+        assertThat(sessionId).isGreaterThan(0L);
+        try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+            blobData.writeToSession(session, 0, partialFileSize);
+        }
+
+        StorageStats afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // 'partialFileSize' bytes were written, verify the size increase.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(partialFileSize);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(partialFileSize);
+
+        // Complete writing data.
+        final long totalFileSize = blobData.getFileSize();
+        try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+            blobData.writeToSession(session, partialFileSize, totalFileSize - partialFileSize);
+        }
+
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // 'totalFileSize' bytes were written so far, verify the size increase.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(totalFileSize);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(totalFileSize);
+
+        // Commit the session.
+        try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+            blobData.writeToSession(session, partialFileSize, session.getSize() - partialFileSize);
+            final CompletableFuture<Integer> callback = new CompletableFuture<>();
+            session.commit(mContext.getMainExecutor(), callback::complete);
+            assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                    .isEqualTo(0);
+        }
+
+        mBlobStoreManager.acquireLease(blobData.getBlobHandle(), R.string.test_desc);
+
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // Session was committed but no one else is using it, verify the size increase stays
+        // the same as earlier.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(totalFileSize);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(totalFileSize);
+
+        mBlobStoreManager.releaseLease(blobData.getBlobHandle());
+
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // No leases on the blob, so it should not be attributed.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(0L);
+    }
+
+    @Test
+    public void testStorageAttribution_acquireLease() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData(mContext);
+        blobData.prepare();
+
+        final StorageStatsManager storageStatsManager = mContext.getSystemService(
+                StorageStatsManager.class);
+        StorageStats beforeStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats beforeStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+        try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+            blobData.writeToSession(session);
+            session.allowPublicAccess();
+
+            final CompletableFuture<Integer> callback = new CompletableFuture<>();
+            session.commit(mContext.getMainExecutor(), callback::complete);
+            assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                    .isEqualTo(0);
+        }
+
+        StorageStats afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // No leases on the blob, so it should not be attributed.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(0L);
+
+        final ICommandReceiver commandReceiver = bindToHelperService();
+
+        StorageStats beforeStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+        StorageStats beforeStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+        commandReceiver.acquireLease(blobData.getBlobHandle());
+
+        StorageStats afterStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+        StorageStats afterStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+        assertThat(afterStatsForHelperPkg.getDataBytes() - beforeStatsForHelperPkg.getDataBytes())
+                .isEqualTo(blobData.getFileSize());
+        assertThat(afterStatsForHelperUid.getDataBytes() - beforeStatsForHelperUid.getDataBytes())
+                .isEqualTo(blobData.getFileSize());
+
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // There shouldn't be no change in stats for this package
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(0L);
+
+        commandReceiver.releaseLease(blobData.getBlobHandle());
+
+        afterStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+        afterStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+        // Lease is released, so it should not be attributed anymore.
+        assertThat(afterStatsForHelperPkg.getDataBytes() - beforeStatsForHelperPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForHelperUid.getDataBytes() - beforeStatsForHelperUid.getDataBytes())
+                .isEqualTo(0L);
+    }
+
+    private ICommandReceiver bindToHelperService() throws Exception {
+        final TestServiceConnection serviceConnection = new TestServiceConnection();
+        final Intent intent = new Intent()
+                .setComponent(new ComponentName(HELPER_PKG, HELPER_SERVICE));
+        mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+        return ICommandReceiver.Stub.asInterface(serviceConnection.getService());
+    }
+
+    private class TestServiceConnection implements ServiceConnection {
+        private BlockingQueue<IBinder> mBlockingQueue = new LinkedBlockingQueue<>();
+
+        public void onServiceConnected(ComponentName componentName, IBinder service) {
+            Log.i(TAG, "Service got connected: " + componentName);
+            mBlockingQueue.offer(service);
+        }
+
+        public void onServiceDisconnected(ComponentName componentName) {
+            Log.e(TAG, "Service got disconnected: " + componentName);
+        }
+
+        public IBinder getService() throws Exception {
+            final IBinder service = mBlockingQueue.poll(TIMEOUT_BIND_SERVICE_SEC,
+                    TimeUnit.SECONDS);
+            return service;
+        }
+    }
+
     private long createSession(BlobHandle blobHandle) throws Exception {
         final long sessionId = mBlobStoreManager.createSession(blobHandle);
         mCreatedSessionIds.add(sessionId);
         return sessionId;
     }
+
+    private String executeCmd(String cmd) {
+        final String result = runShellCommand(cmd).trim();
+        Log.d(TAG, "Output of <" + cmd + ">: <" + result + ">");
+        return result;
+    }
 }
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 9603ec7..c1a02ab2 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -145,55 +145,58 @@
         }
     }
 
-    public void testSetSecurityLoggingEnabled_failIfNotDeviceOwner() {
+    public void testSetSecurityLoggingEnabled_failIfNotOrganizationOwnedProfileOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_failIfNotDeviceOwner");
+            Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_"
+                    + "failIfNotOrganizationOwnedProfileOwner");
             return;
         }
         try {
             mDevicePolicyManager.setSecurityLoggingEnabled(mComponent, true);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
+            assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
         }
     }
 
-    public void testIsSecurityLoggingEnabled_failIfNotDeviceOwner() {
+    public void testIsSecurityLoggingEnabled_failIfNotOrganizationOwnedProfileOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_failIfNotDeviceOwner");
+            Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_"
+                    + "failIfNotOrganizationOwnedProfileOwner");
             return;
         }
         try {
             mDevicePolicyManager.isSecurityLoggingEnabled(mComponent);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
+            assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
         }
     }
 
-    public void testRetrieveSecurityLogs_failIfNotDeviceOwner() {
+    public void testRetrieveSecurityLogs_failIfNotOrganizationOwnedProfileOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotDeviceOwner");
+            Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotOrganizationOwnedProfileOwner");
             return;
         }
         try {
             mDevicePolicyManager.retrieveSecurityLogs(mComponent);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
+            assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
         }
     }
 
-    public void testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner() {
+    public void testRetrievePreRebootSecurityLogs_failIfNotOrganizationOwnedProfileOwner() {
         if (!mDeviceAdmin) {
-            Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner");
+            Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_"
+                    + "failIfNotOrganizationOwnedProfileOwner");
             return;
         }
         try {
             mDevicePolicyManager.retrievePreRebootSecurityLogs(mComponent);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
+            assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
         }
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index c2094c0..cd099d7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -827,8 +827,6 @@
                 return this;
             }
 
-
-
             /**
              * Sets the view to present the response in the UI.
              */
@@ -853,6 +851,9 @@
                 return this;
             }
 
+            /**
+             * Builds the canned dataset.
+             */
             public CannedDataset build() {
                 return new CannedDataset(this);
             }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 15386b0..136bcba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -70,6 +70,7 @@
 
 import com.android.compatibility.common.util.RetryableException;
 import com.android.compatibility.common.util.Timeout;
+import com.android.cts.mockime.MockIme;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -262,6 +263,14 @@
     }
 
     /**
+     * Asserts the suggestion strip was never shown.
+     */
+    public void assertNoSuggestionStripEver() throws Exception {
+        assertNeverShown("suggestion strip", SUGGESTION_STRIP_SELECTOR,
+                DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
+    }
+
+    /**
      * Asserts the dataset chooser is shown and contains exactly the given datasets.
      *
      * @return the dataset picker object.
@@ -335,12 +344,25 @@
         return picker;
     }
 
+    /**
+     * Asserts the suggestion strip on the {@link MockIme} is shown and contains the given number
+     * of child suggestions.
+     *
+     * @param childrenCount the expected number of children.
+     *
+     * @return the suggestion strip object
+     */
     public UiObject2 assertSuggestionStrip(int childrenCount) throws Exception {
         final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
         assertThat(strip.getChildCount()).isEqualTo(childrenCount);
         return strip;
     }
 
+    /**
+     * Selects the suggestion in the {@link MockIme}'s suggestion strip at the given index.
+     *
+     * @param index the index of the suggestion to select.
+     */
     public void selectSuggestion(int index) throws Exception {
         final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
         assertThat(index).isAtLeast(0);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index 284d549..39139eb 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -22,6 +22,7 @@
 import static android.autofillservice.cts.Helper.findAutofillIdByResourceId;
 import static android.autofillservice.cts.Helper.findNodeByResourceId;
 import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.InstrumentedAutoFillService.waitUntilDisconnected;
 import static android.autofillservice.cts.Timeouts.MOCK_IME_TIMEOUT_MS;
 import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
 
@@ -40,7 +41,6 @@
 import android.autofillservice.cts.InstrumentedAutoFillService;
 import android.os.Process;
 import android.service.autofill.FillContext;
-import android.support.test.uiautomator.UiObject2;
 
 import com.android.compatibility.common.util.RetryableException;
 import com.android.cts.mockime.ImeEventStream;
@@ -60,29 +60,14 @@
     }
 
     @Test
-    public void testAutofill_oneDataset() throws Exception {
+    public void testAutofill_noDataset() throws Exception {
         // Set service.
         enableService();
 
         final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
         assumeTrue("MockIME not available", mockImeSession != null);
 
-        // Set expectations.
-        String expectedHeader = null, expectedFooter = null;
-
-        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
-                .addDataset(new CannedFillResponse.CannedDataset.Builder()
-                        .setField(ID_USERNAME, "dude")
-                        .setField(ID_PASSWORD, "sweet")
-                        .setPresentation(createPresentation("The Dude"))
-                        .setInlinePresentation(createInlinePresentation("The Dude"))
-                        .build());
-
-        sReplier.addResponse(builder.build());
-        mActivity.expectAutoFill("dude", "sweet");
-
-        // Dynamically set password to make sure it's sanitized.
-        mActivity.onPassword((v) -> v.setText("I AM GROOT"));
+        sReplier.addResponse(CannedFillResponse.NO_RESPONSE);
 
         final ImeEventStream stream = mockImeSession.openEventStream();
         mockImeSession.callRequestShowSelf(0);
@@ -95,65 +80,50 @@
         expectEvent(stream, editorMatcher("onStartInput", mActivity.getUsername().getId()),
                 MOCK_IME_TIMEOUT_MS);
 
-        //TODO: extServices bug cause test to fail first time, retry if suggestion strip missing.
-        try {
-            expectEvent(stream, event -> "onSuggestionViewUpdated".equals(event.getEventName()),
-                    MOCK_IME_TIMEOUT_MS);
-        } catch (TimeoutException e) {
-            sReplier.getNextFillRequest();
-            throw new RetryableException("Retry inline test");
-        }
+        sReplier.getNextFillRequest();
 
-        final UiObject2 suggestionStrip = mUiBot.assertSuggestionStrip(1);
-        mUiBot.selectSuggestion(0);
+        mUiBot.assertNoSuggestionStripEver();
+        mUiBot.assertNoDatasetsEver();
 
-        // Check the results.
-        mActivity.assertAutoFilled();
-
-        // Sanity checks.
-
-        // Make sure input was sanitized.
-        final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
-        assertWithMessage("CancelationSignal is null").that(request.cancellationSignal).isNotNull();
-        assertTextIsSanitized(request.structure, ID_PASSWORD);
-        final FillContext fillContext = request.contexts.get(request.contexts.size() - 1);
-        assertThat(fillContext.getFocusedId())
-                .isEqualTo(findAutofillIdByResourceId(fillContext, ID_USERNAME));
-
-        // Make sure initial focus was properly set.
-        assertWithMessage("Username node is not focused").that(
-                findNodeByResourceId(request.structure, ID_USERNAME).isFocused()).isTrue();
-        assertWithMessage("Password node is focused").that(
-                findNodeByResourceId(request.structure, ID_PASSWORD).isFocused()).isFalse();
+        waitUntilDisconnected();
     }
 
     @Test
-    public void testAutofill_twoDatasets() throws Exception {
+    public void testAutofill_oneDataset() throws Exception {
+        testBasicLoginAutofill(/* numDatasets= */ 1, /* selectedDatasetIndex= */ 0);
+    }
+
+    @Test
+    public void testAutofill_twoDatasets_selectFirstDataset() throws Exception {
+        testBasicLoginAutofill(/* numDatasets= */ 2, /* selectedDatasetIndex= */ 0);
+
+    }
+
+    @Test
+    public void testAutofill_twoDatasets_selectSecondDataset() throws Exception {
+        testBasicLoginAutofill(/* numDatasets= */ 2, /* selectedDatasetIndex= */ 1);
+    }
+
+    private void testBasicLoginAutofill(int numDatasets, int selectedDatasetIndex)
+            throws Exception {
         // Set service.
         enableService();
 
         final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
         assumeTrue("MockIME not available", mockImeSession != null);
 
-        // Set expectations.
-        String expectedHeader = null, expectedFooter = null;
-
-        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
-                .addDataset(new CannedFillResponse.CannedDataset.Builder()
-                        .setField(ID_USERNAME, "dude")
-                        .setField(ID_PASSWORD, "sweet")
-                        .setPresentation(createPresentation("The Dude"))
-                        .setInlinePresentation(createInlinePresentation("The Dude"))
-                        .build())
-                .addDataset(new CannedFillResponse.CannedDataset.Builder()
-                        .setField(ID_USERNAME, "test")
-                        .setField(ID_PASSWORD, "tweet")
-                        .setPresentation(createPresentation("Second Dude"))
-                        .setInlinePresentation(createInlinePresentation("Second Dude"))
-                        .build());
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder();
+        for (int i = 0; i < numDatasets; i++) {
+            builder.addDataset(new CannedFillResponse.CannedDataset.Builder()
+                    .setField(ID_USERNAME, "dude" + i)
+                    .setField(ID_PASSWORD, "sweet" + i)
+                    .setPresentation(createPresentation("The Dude" + i))
+                    .setInlinePresentation(createInlinePresentation("The Dude" + i))
+                    .build());
+        }
 
         sReplier.addResponse(builder.build());
-        mActivity.expectAutoFill("test", "tweet");
+        mActivity.expectAutoFill("dude" + selectedDatasetIndex, "sweet" + selectedDatasetIndex);
 
         // Dynamically set password to make sure it's sanitized.
         mActivity.onPassword((v) -> v.setText("I AM GROOT"));
@@ -178,14 +148,14 @@
             throw new RetryableException("Retry inline test");
         }
 
-        mUiBot.assertSuggestionStrip(2);
-        mUiBot.selectSuggestion(1);
+        mUiBot.assertSuggestionStrip(numDatasets);
+        mUiBot.assertNoDatasetsEver();
+
+        mUiBot.selectSuggestion(selectedDatasetIndex);
 
         // Check the results.
         mActivity.assertAutoFilled();
 
-        // Sanity checks.
-
         // Make sure input was sanitized.
         final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
         assertWithMessage("CancelationSignal is null").that(request.cancellationSignal).isNotNull();
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index 9dcc34f..31218db 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -939,18 +939,28 @@
     }
 
     camera_status_t initWithErrorLog() {
+        return initWithErrorLog(nullptr /*env*/, nullptr /*jOverrideCameraId*/);
+    }
+
+    camera_status_t initWithErrorLog(JNIEnv* env, jstring jOverrideCameraId) {
         camera_status_t ret = ACameraManager_getCameraIdList(
                 mCameraManager, &mCameraIdList);
         if (ret != ACAMERA_OK) {
             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
             return ret;
         }
+
+        if (env != nullptr && jOverrideCameraId != nullptr) {
+            mOverrideCameraId = env->GetStringUTFChars(jOverrideCameraId, 0);
+        }
         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
         if (ret != ACAMERA_OK) {
             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
             return ret;
         }
         mMgrInited = true;
+        mJOverrideCameraId = jOverrideCameraId;
+        mJNIEnv = env;
         return ACAMERA_OK;
     }
 
@@ -971,6 +981,12 @@
             mCameraIdList = nullptr;
         }
         mMgrInited = false;
+        if (mOverrideCameraId != nullptr && mJNIEnv != nullptr) {
+            mJNIEnv->ReleaseStringUTFChars(mJOverrideCameraId, mOverrideCameraId);
+            mOverrideCameraId = nullptr;
+            mJOverrideCameraId = nullptr;
+            mJNIEnv = nullptr;
+        }
         return ACAMERA_OK;
     }
 
@@ -978,6 +994,9 @@
         if (!mMgrInited || !mCameraIdList) {
             return -1;
         }
+        if (mOverrideCameraId != nullptr) {
+            return 1;
+        }
         return mCameraIdList->numCameras;
     }
 
@@ -985,6 +1004,13 @@
         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
             return nullptr;
         }
+        if (mOverrideCameraId != nullptr) {
+            if (idx >= 1) {
+                return nullptr;
+            } else {
+                return mOverrideCameraId;
+            }
+        }
         return mCameraIdList->cameraIds[idx];
     }
 
@@ -993,10 +1019,18 @@
         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
             return nullptr;
         }
+        const char* cameraId = mCameraIdList->cameraIds[idx];
+        if (mOverrideCameraId != nullptr) {
+            if (idx >= 1) {
+                return nullptr;
+            } else {
+                cameraId = mOverrideCameraId;
+            }
+        }
 
         ACameraMetadata* chars;
         camera_status_t ret = ACameraManager_getCameraCharacteristics(
-                mCameraManager, mCameraIdList->cameraIds[idx], &chars);
+                mCameraManager, cameraId, &chars);
         if (ret != ACAMERA_OK) {
             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
             return nullptr;
@@ -1618,6 +1652,9 @@
     ACameraOutputTarget* mReqPreviewOutput = nullptr;
     ACameraOutputTarget* mReqImgReaderOutput = nullptr;
     const char* mCameraId;
+    JNIEnv* mJNIEnv = nullptr;
+    jstring mJOverrideCameraId;
+    const char* mOverrideCameraId = nullptr;
 
     bool mMgrInited = false; // cameraId, serviceListener
     bool mImgReaderInited = false;
@@ -2014,13 +2051,13 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceOpenAndCloseNative(
-        JNIEnv* env, jclass /*clazz*/) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     int numCameras = 0;
     bool pass = false;
     PreviewTestCase testCase;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -2084,7 +2121,7 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceCreateCaptureRequestNative(
-        JNIEnv* env, jclass /*clazz*/) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     bool pass = false;
     ACameraManager* mgr = ACameraManager_create();
@@ -2095,9 +2132,18 @@
     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
 
     int numCameras = cameraIdList->numCameras;
+    const char* overrideCameraId = nullptr;
+    if (jOverrideCameraId != nullptr) {
+        overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
+    }
+
     for (int i = 0; i < numCameras; i++) {
         CameraDeviceListener deviceListener;
         const char* cameraId = cameraIdList->cameraIds[i];
+        if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
+            // Skip other cameras if overriding camera id to be tested.
+            continue;
+        }
         ACameraDevice_StateCallbacks deviceCb {
             &deviceListener,
             CameraDeviceListener::onDisconnected,
@@ -2322,13 +2368,14 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceSessionOpenAndCloseNative(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     int numCameras = 0;
     bool pass = false;
     PreviewTestCase testCase;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -2460,7 +2507,8 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceSharedOutputUpdate(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     int numCameras = 0;
     bool pass = false;
@@ -2477,7 +2525,7 @@
     uint32_t timeoutSec = 1;
     uint32_t runPreviewSec = 2;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -2729,13 +2777,14 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceSimplePreviewNative(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     int numCameras = 0;
     bool pass = false;
     PreviewTestCase testCase;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -2837,7 +2886,8 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDevicePreviewWithSessionParametersNative(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     int numCameras = 0;
     bool pass = false;
@@ -2845,7 +2895,7 @@
     ACameraMetadata* chars = nullptr;
     PreviewTestCase testCase;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -2965,7 +3015,8 @@
 }
 
 bool nativeCameraDeviceLogicalPhysicalStreaming(
-        JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings) {
+        JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
+        jstring jOverrideCameraId) {
     const int NUM_TEST_IMAGES = 10;
     const int TEST_WIDTH  = 640;
     const int TEST_HEIGHT = 480;
@@ -2981,7 +3032,7 @@
     uint32_t timeoutSec = 1;
     uint32_t runPreviewSec = 2;
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -3244,22 +3295,26 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceLogicalPhysicalStreamingNative(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     return nativeCameraDeviceLogicalPhysicalStreaming(env,
-            jPreviewSurface, false /*usePhysicalSettings*/);
+            jPreviewSurface, false /*usePhysicalSettings*/,
+            jOverrideCameraId);
 }
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
 testCameraDeviceLogicalPhysicalSettingsNative(
-        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     return nativeCameraDeviceLogicalPhysicalStreaming(env,
-            jPreviewSurface, true /*usePhysicalSettings*/);
+            jPreviewSurface, true /*usePhysicalSettings*/,
+            jOverrideCameraId);
 }
 
-
 bool nativeImageReaderTestBase(
-        JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb) {
+        JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
+        jstring jOverrideCameraId) {
     const int NUM_TEST_IMAGES = 10;
     const int TEST_WIDTH  = 640;
     const int TEST_HEIGHT = 480;
@@ -3275,7 +3330,7 @@
         ALOGI("%s: out path is %s", __FUNCTION__, outPath);
     }
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
@@ -3523,7 +3578,7 @@
 // surface will eventually run out of free buffers and start reporting capture errors.
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
-testCameraDeviceCaptureFailureNative(JNIEnv* env) {
+testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
     const size_t NUM_TEST_IMAGES = 10;
     const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
     const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
@@ -3536,7 +3591,7 @@
     uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
                               // timeout
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto exit;
@@ -3697,46 +3752,51 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
 testJpegNative(
-        JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
-            ImageReaderListener::validateImageCb);
+            ImageReaderListener::validateImageCb, jOverrideCameraId);
 }
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
 testY8Native(
-        JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
-            ImageReaderListener::validateImageCb);
+            ImageReaderListener::validateImageCb, jOverrideCameraId);
 }
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
 testHeicNative(
-        JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
-            ImageReaderListener::validateImageCb);
+            ImageReaderListener::validateImageCb, jOverrideCameraId);
 }
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
 testDepthJpegNative(
-        JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
-            ImageReaderListener::validateImageCb);
+            ImageReaderListener::validateImageCb, jOverrideCameraId);
 }
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
 testImageReaderCloseAcquiredImagesNative(
-        JNIEnv* env, jclass /*clazz*/) {
+        JNIEnv* env, jclass /*clazz*/,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
-            ImageReaderListener::acquireImageCb);
+            ImageReaderListener::acquireImageCb, jOverrideCameraId);
 }
 
 template <>
@@ -3858,7 +3918,8 @@
 extern "C" jboolean
 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
 testStillCaptureNative(
-        JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
+        JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
+        jstring jOverrideCameraId) {
     ALOGV("%s", __FUNCTION__);
     const int NUM_TEST_IMAGES = 10;
     const int TEST_WIDTH  = 640;
@@ -3872,7 +3933,7 @@
     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
 
-    camera_status_t ret = testCase.initWithErrorLog();
+    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
     if (ret != ACAMERA_OK) {
         // Don't log error here. testcase did it
         goto cleanup;
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 990cf31..19223b0 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -572,6 +572,10 @@
      */
     @Test
     public void testCameraManagerListenerCallbacks() throws Exception {
+        if (mOverrideCameraId != null) {
+            // Testing is done for individual camera. Skip.
+            return;
+        }
         testCameraManagerListenerCallbacks(/*useExecutor*/ false);
         testCameraManagerListenerCallbacks(/*useExecutor*/ true);
     }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 30dba3e..770f3e4 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -2428,6 +2428,10 @@
             // Skip test, http://b/141496896
             return;
         }
+        if (mOverrideCameraId != null) {
+            // A single camera is being tested. Skip test.
+            return;
+        }
         int legacyDeviceCount = Camera.getNumberOfCameras();
         assertTrue("More legacy devices: " + legacyDeviceCount + " compared to Camera2 devices: " +
                 mCharacteristics.size(), legacyDeviceCount <= mCharacteristics.size());
diff --git a/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java b/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
index fc09e51..dc34087 100644
--- a/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
@@ -25,6 +25,7 @@
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
+import android.hardware.cts.helpers.CameraUtils;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CaptureRequest;
@@ -193,7 +194,8 @@
     @Presubmit
     @Test
     public void testCamera1() throws Exception {
-        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
+        int[] cameraIds = CameraUtils.deriveCameraIdsUnderTest();
+        for (int i : cameraIds) {
             Camera camera = null;
             try {
                 Log.i(TAG, "Testing android.hardware.Camera API for camera device " + i);
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
index 207c3e3..ff1d790 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
@@ -47,13 +47,13 @@
     @Test
     public void testCameraDeviceOpenAndClose() {
         assertTrue("testCameraDeviceOpenAndClose fail, see log for details",
-                testCameraDeviceOpenAndCloseNative());
+                testCameraDeviceOpenAndCloseNative(mOverrideCameraId));
     }
 
     @Test
     public void testCameraDeviceCreateCaptureRequest() {
         assertTrue("testCameraDeviceCreateCaptureRequest fail, see log for details",
-                testCameraDeviceCreateCaptureRequestNative());
+                testCameraDeviceCreateCaptureRequestNative(mOverrideCameraId));
     }
 
     @Test
@@ -61,7 +61,7 @@
         // Init preview surface to a guaranteed working size
         updatePreviewSurface(new Size(640, 480));
         assertTrue("testCameraDeviceSessionOpenAndClose fail, see log for details",
-                testCameraDeviceSessionOpenAndCloseNative(mPreviewSurface));
+                testCameraDeviceSessionOpenAndCloseNative(mPreviewSurface, mOverrideCameraId));
     }
 
     @Test
@@ -69,7 +69,7 @@
         // Init preview surface to a guaranteed working size
         updatePreviewSurface(new Size(640, 480));
         assertTrue("testCameraDeviceSimplePreview fail, see log for details",
-                testCameraDeviceSimplePreviewNative(mPreviewSurface));
+                testCameraDeviceSimplePreviewNative(mPreviewSurface, mOverrideCameraId));
     }
 
     @Test
@@ -77,7 +77,8 @@
         // Init preview surface to a guaranteed working size
         updatePreviewSurface(new Size(640, 480));
         assertTrue("testCameraDevicePreviewWithSessionParameters fail, see log for details",
-                testCameraDevicePreviewWithSessionParametersNative(mPreviewSurface));
+                testCameraDevicePreviewWithSessionParametersNative(mPreviewSurface,
+                mOverrideCameraId));
     }
 
     @Test
@@ -89,7 +90,8 @@
         outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
         Surface outputSurface = new Surface(outputTexture);
         assertTrue("testCameraDeviceSharedOutputUpdate fail, see log for details",
-                testCameraDeviceSharedOutputUpdate(mPreviewSurface, outputSurface));
+                testCameraDeviceSharedOutputUpdate(mPreviewSurface, outputSurface,
+                mOverrideCameraId));
     }
 
     @Test
@@ -101,7 +103,7 @@
         outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
         Surface outputSurface = new Surface(outputTexture);
         assertTrue("testCameraDeviceLogicalPhysicalStreaming fail, see log for details",
-                testCameraDeviceLogicalPhysicalStreamingNative(mPreviewSurface));
+                testCameraDeviceLogicalPhysicalStreamingNative(mPreviewSurface, mOverrideCameraId));
     }
 
     @Test
@@ -113,24 +115,30 @@
         outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
         Surface outputSurface = new Surface(outputTexture);
         assertTrue("testCameraDeviceLogicalPhysicalSettings fail, see log for details",
-                testCameraDeviceLogicalPhysicalSettingsNative(mPreviewSurface));
+                testCameraDeviceLogicalPhysicalSettingsNative(mPreviewSurface, mOverrideCameraId));
     }
 
     @Test
     public void testCameraDeviceCaptureFailure() {
         assertTrue("testCameraDeviceCaptureFailure fail, see log for details",
-                testCameraDeviceCaptureFailureNative());
+                testCameraDeviceCaptureFailureNative(mOverrideCameraId));
     }
 
-    private static native boolean testCameraDeviceOpenAndCloseNative();
-    private static native boolean testCameraDeviceCreateCaptureRequestNative();
-    private static native boolean testCameraDeviceSessionOpenAndCloseNative(Surface preview);
-    private static native boolean testCameraDeviceSimplePreviewNative(Surface preview);
+    private static native boolean testCameraDeviceOpenAndCloseNative(String overrideCameraId);
+    private static native boolean testCameraDeviceCreateCaptureRequestNative(
+            String overrideCameraId);
+    private static native boolean testCameraDeviceSessionOpenAndCloseNative(Surface preview,
+            String overrideCameraId);
+    private static native boolean testCameraDeviceSimplePreviewNative(Surface preview,
+            String overrideCameraId);
     private static native boolean testCameraDevicePreviewWithSessionParametersNative(
-            Surface preview);
-    private static native boolean testCameraDeviceSharedOutputUpdate(Surface src, Surface dst);
-    private static native boolean testCameraDeviceLogicalPhysicalStreamingNative(Surface preview);
-    private static native boolean testCameraDeviceLogicalPhysicalSettingsNative(Surface preview);
-    private static native boolean testCameraDeviceCaptureFailureNative();
+            Surface preview, String overrideCameraId);
+    private static native boolean testCameraDeviceSharedOutputUpdate(Surface src, Surface dst,
+            String overrideCameraId);
+    private static native boolean testCameraDeviceLogicalPhysicalStreamingNative(Surface preview,
+            String overrideCameraId);
+    private static native boolean testCameraDeviceLogicalPhysicalSettingsNative(Surface preview,
+            String overrideCameraId);
+    private static native boolean testCameraDeviceCaptureFailureNative(String overrideCameraId);
 
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
index 493e670..ef9a57c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
@@ -43,36 +43,36 @@
     @Test
     public void testJpeg() {
         assertTrue("testJpeg fail, see log for details",
-                testJpegNative(mDebugFileNameBase));
+                testJpegNative(mDebugFileNameBase, mOverrideCameraId));
     }
 
     @Test
     public void testY8() {
         assertTrue("testY8 fail, see log for details",
-                testY8Native(mDebugFileNameBase));
+                testY8Native(mDebugFileNameBase, mOverrideCameraId));
     }
 
     @Test
     public void testHeic() {
         assertTrue("testHeic fail, see log for details",
-                testHeicNative(mDebugFileNameBase));
+                testHeicNative(mDebugFileNameBase, mOverrideCameraId));
     }
 
     @Test
     public void testDepthJpeg() {
         assertTrue("testDepthJpeg fail, see log for details",
-                testDepthJpegNative(mDebugFileNameBase));
+                testDepthJpegNative(mDebugFileNameBase, mOverrideCameraId));
     }
 
     @Test
     public void testImageReaderCloseAcquiredImages() {
         assertTrue("testImageReaderClose fail, see log for details",
-                testImageReaderCloseAcquiredImagesNative());
+                testImageReaderCloseAcquiredImagesNative(mOverrideCameraId));
     }
 
-    private static native boolean testJpegNative(String filePath);
-    private static native boolean testY8Native(String filePath);
-    private static native boolean testHeicNative(String filePath);
-    private static native boolean testDepthJpegNative(String filePath);
-    private static native boolean testImageReaderCloseAcquiredImagesNative();
+    private static native boolean testJpegNative(String filePath, String overrideCameraId);
+    private static native boolean testY8Native(String filePath, String overrideCameraId);
+    private static native boolean testHeicNative(String filePath, String overrideCameraId);
+    private static native boolean testDepthJpegNative(String filePath, String overrideCameraId);
+    private static native boolean testImageReaderCloseAcquiredImagesNative(String overrideCameraId);
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
index a778f7d..cfefd62 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
@@ -48,9 +48,9 @@
         // Init preview surface to a guaranteed working size
         updatePreviewSurface(new Size(640, 480));
         assertTrue("testStillCapture fail, see log for details",
-                testStillCaptureNative(mDebugFileNameBase, mPreviewSurface));
+                testStillCaptureNative(mDebugFileNameBase, mPreviewSurface, mOverrideCameraId));
     }
 
     private static native boolean testStillCaptureNative(
-            String filePath, Surface previewSurface);
+            String filePath, Surface previewSurface, String overrideCameraId);
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
index 91f6b80..13ce89a 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
@@ -38,12 +38,15 @@
 import android.media.Image;
 import android.media.Image.Plane;
 import android.media.ImageReader;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.util.Log;
 import android.view.Surface;
 import android.view.WindowManager;
 
+import androidx.test.InstrumentationRegistry;
+
 import com.android.ex.camera2.blocking.BlockingSessionCallback;
 import com.android.ex.camera2.blocking.BlockingStateCallback;
 
@@ -87,6 +90,10 @@
     private WindowManager mWindowManager;
     private Context mContext;
 
+    private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+    private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+    private static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
     public Camera2AndroidTestRule(Context context) {
         mContext = context;
     }
@@ -175,6 +182,20 @@
         return mCollector;
     }
 
+    private String[] deriveCameraIdsUnderTest() throws Exception {
+        String[] idsUnderTest = mCameraManager.getCameraIdListNoLazy();
+        assertNotNull("Camera ids shouldn't be null", idsUnderTest);
+        if (mOverrideCameraId != null) {
+            if (Arrays.asList(idsUnderTest).contains(mOverrideCameraId)) {
+                idsUnderTest = new String[]{mOverrideCameraId};
+            } else {
+                idsUnderTest = new String[]{};
+            }
+        }
+
+        return idsUnderTest;
+    }
+
     /**
      * Set up the camera2 test case required environments, including CameraManager,
      * HandlerThread, Camera IDs, and CameraStateCallback etc.
@@ -193,8 +214,7 @@
          */
         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
 
-        mCameraIdsUnderTest = mCameraManager.getCameraIdListNoLazy();
-        assertNotNull("Camera ids shouldn't be null", mCameraIdsUnderTest);
+        mCameraIdsUnderTest = deriveCameraIdsUnderTest();
         mHandlerThread = new HandlerThread(TAG);
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
@@ -239,8 +259,7 @@
         Log.v(TAG, "Tear down...");
         if (mCameraManager != null) {
             try {
-                String[] cameraIdsPostTest = mCameraManager.getCameraIdListNoLazy();
-                assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
+                String[] cameraIdsPostTest = deriveCameraIdsUnderTest();
                 Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIdsUnderTest));
                 Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
                 assertTrue(
@@ -710,4 +729,4 @@
             // Expected.
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
index c83f074..a9e82ef 100644
--- a/tests/camera/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -78,6 +78,7 @@
     private Looper mLooper = null;
     private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
     private final ConditionVariable mPreviewDone = new ConditionVariable();
+    private int[] mCameraIds;
 
     Camera mCamera;
     boolean mIsExternalCamera;
@@ -105,6 +106,8 @@
         GLSurfaceViewCtsActivity ctsActivity = mActivityRule.getActivity();
         // Store a link to the view so we can redraw it when needed
         mGLView = ctsActivity.getView();
+
+        mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
     }
 
     @After
@@ -324,8 +327,7 @@
         wl.acquire();
         try {
             /* Run the requested test per camera */
-            int nCameras = Camera.getNumberOfCameras();
-            for (int id = 0; id < nCameras; id++) {
+            for (int id : mCameraIds) {
                 Log.v(TAG, "Camera id=" + id);
                 test.run(id);
             }
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 47ffca6..c8330f7 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -124,6 +124,7 @@
     private final ConditionVariable mPreviewDone = new ConditionVariable();
     private final ConditionVariable mFocusDone = new ConditionVariable();
     private final ConditionVariable mSnapshotDone = new ConditionVariable();
+    private int[] mCameraIds;
 
     Camera mCamera;
     boolean mIsExternalCamera;
@@ -134,6 +135,7 @@
 
     @Before
     public void setUp() throws Exception {
+        mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
     }
 
     @After
@@ -408,8 +410,7 @@
     @UiThreadTest
     @Test
     public void testTakePicture() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             mCamera.startPreview();
@@ -454,8 +455,7 @@
     @UiThreadTest
     @Test
     public void testPreviewCallback() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewCallbackByCamera(id);
         }
@@ -509,8 +509,7 @@
     @UiThreadTest
     @Test
     public void testStabilizationOneShotPreviewCallback() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testStabilizationOneShotPreviewCallbackByCamera(id);
         }
@@ -535,8 +534,7 @@
     @UiThreadTest
     @Test
     public void testSetOneShotPreviewCallback() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testSetOneShotPreviewCallbackByCamera(id);
         }
@@ -559,8 +557,7 @@
     @UiThreadTest
     @Test
     public void testSetPreviewDisplay() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testSetPreviewDisplayByCamera(id);
         }
@@ -603,8 +600,7 @@
     @UiThreadTest
     @Test
     public void testDisplayOrientation() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testDisplayOrientationByCamera(id);
         }
@@ -642,8 +638,7 @@
     @UiThreadTest
     @Test
     public void testParameters() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testParametersByCamera(id);
         }
@@ -866,8 +861,7 @@
     @UiThreadTest
     @Test
     public void testJpegThumbnailSize() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             testJpegThumbnailSizeByCamera(false, 0, 0);
@@ -940,8 +934,7 @@
     @UiThreadTest
     @Test
     public void testJpegExif() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             testJpegExifByCamera(false);
@@ -1233,8 +1226,7 @@
     @UiThreadTest
     @Test
     public void testLockUnlock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testLockUnlockByCamera(id);
         }
@@ -1426,8 +1418,7 @@
     @UiThreadTest
     @Test
     public void testPreviewCallbackWithBuffer() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewCallbackWithBufferByCamera(id);
         }
@@ -1524,8 +1515,7 @@
     @UiThreadTest
     @Test
     public void testImmediateZoom() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testImmediateZoomByCamera(id);
         }
@@ -1596,8 +1586,7 @@
     @UiThreadTest
     @Test
     public void testSmoothZoom() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testSmoothZoomByCamera(id);
         }
@@ -1722,8 +1711,7 @@
     @UiThreadTest
     @Test
     public void testFocusDistances() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testFocusDistancesByCamera(id);
         }
@@ -1831,8 +1819,7 @@
     @UiThreadTest
     @Test
     public void testCancelAutofocus() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testCancelAutofocusByCamera(id);
         }
@@ -1913,6 +1900,11 @@
     @UiThreadTest
     @Test
     public void testMultipleCameras() throws Exception {
+        if (CameraUtils.mOverrideCameraId != null) {
+            // A single camera is being tested. Skip.
+            return;
+        }
+
         int nCameras = Camera.getNumberOfCameras();
         Log.v(TAG, "total " + nCameras + " cameras");
         assertTrue(nCameras >= 0);
@@ -1976,8 +1968,7 @@
     @UiThreadTest
     @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
     public void testPreviewPictureSizesCombination() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewPictureSizesCombinationByCamera(id);
         }
@@ -2093,8 +2084,7 @@
     @UiThreadTest
     @Test
     public void testPreviewFpsRange() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewFpsRangeByCamera(id);
         }
@@ -2322,8 +2312,7 @@
     @UiThreadTest
     @Test
     public void testSceneMode() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testSceneModeByCamera(id);
         }
@@ -2423,8 +2412,7 @@
     @UiThreadTest
     @Test
     public void testInvalidParameters() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testInvalidParametersByCamera(id);
         }
@@ -2478,8 +2466,7 @@
     @UiThreadTest
     @Test
     public void testGetParameterDuringFocus() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testGetParameterDuringFocusByCamera(id);
         }
@@ -2514,8 +2501,7 @@
     @UiThreadTest
     @Test
     public void testPreviewFormats() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewFormatsByCamera(id);
         }
@@ -2539,6 +2525,11 @@
     @UiThreadTest
     @Test
     public void testMultiCameraRelease() throws Exception {
+        if (CameraUtils.mOverrideCameraId != null) {
+            // A single camera is being tested. Skip.
+            return;
+        }
+
         // Verify that multiple cameras exist, and that they can be opened at the same time
         if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Checking pre-conditions.");
         int nCameras = Camera.getNumberOfCameras();
@@ -2628,8 +2619,7 @@
     @UiThreadTest
     @Test
     public void testFocusAreas() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
 
             initializeMessageLooper(id);
@@ -2648,8 +2638,7 @@
     @UiThreadTest
     @Test
     public void testMeteringAreas() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             Parameters parameters = mCamera.getParameters();
@@ -2785,8 +2774,7 @@
     @UiThreadTest
     @Test
     public void testJpegCallbackStartPreview() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testJpegCallbackStartPreviewByCamera(id);
         }
@@ -2815,8 +2803,7 @@
     @UiThreadTest
     @Test
     public void testRecordingHint() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testRecordingHintByCamera(id);
         }
@@ -2911,8 +2898,7 @@
     @UiThreadTest
     @Test
     public void testAutoExposureLock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             Parameters parameters = mCamera.getParameters();
@@ -2928,8 +2914,7 @@
     @UiThreadTest
     @Test
     public void testAutoWhiteBalanceLock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             Parameters parameters = mCamera.getParameters();
@@ -2945,8 +2930,7 @@
     @UiThreadTest
     @Test
     public void test3ALockInteraction() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             initializeMessageLooper(id);
             Parameters parameters = mCamera.getParameters();
@@ -3170,8 +3154,7 @@
     @UiThreadTest
     @Test
     public void testFaceDetection() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testFaceDetectionByCamera(id);
         }
@@ -3297,8 +3280,7 @@
     @UiThreadTest
     @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
     public void testVideoSnapshot() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testVideoSnapshotByCamera(id, /*recordingHint*/false);
             testVideoSnapshotByCamera(id, /*recordingHint*/true);
@@ -3378,8 +3360,7 @@
 
     @Test
     public void testPreviewCallbackWithPicture() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testPreviewCallbackWithPictureByCamera(id);
         }
@@ -3438,8 +3419,7 @@
 
     @Test
     public void testEnableShutterSound() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
+        for (int id : mCameraIds) {
             Log.v(TAG, "Camera id=" + id);
             testEnableShutterSoundByCamera(id);
         }
diff --git a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
index 77e75dd..785535c 100644
--- a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
+++ b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
@@ -70,7 +70,8 @@
      * @see {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
      */
     public void testMaxAspectRatios() throws Exception {
-        for (int id = 0; id < Camera.getNumberOfCameras(); ++id) {
+        int[] cameraIds = CameraUtils.deriveCameraIdsUnderTest();
+        for (int id : cameraIds) {
             if (CameraUtils.isLegacyHAL(getContext(), id)) {
 
                 Camera camera = Camera.open(id);
diff --git a/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java b/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
index ac3f6dd..5cc67fd 100644
--- a/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
+++ b/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
@@ -20,6 +20,7 @@
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
 import android.hardware.Camera.Parameters;
+import android.hardware.cts.helpers.CameraUtils;
 import android.os.SystemClock;
 import android.util.Log;
 
@@ -49,29 +50,31 @@
 
     private Instrumentation mInstrumentation;
     private CameraPerformanceTestHelper mHelper;
+    private int[] mCameraIds;
 
     @Before
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mHelper = new CameraPerformanceTestHelper();
+        mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
     }
 
     @After
     public void tearDown() throws Exception {
         if (mHelper.getCamera() != null) {
             mHelper.getCamera().release();
-
         }
     }
 
     @Test
     public void testLegacyApiPerformance() throws Exception {
         final int NUM_TEST_LOOPS = 10;
+        if (mCameraIds.length == 0) return;
 
-        int nCameras = Camera.getNumberOfCameras();
-        double[] avgCameraTakePictureTimes = new double[nCameras];
+        double[] avgCameraTakePictureTimes = new double[mCameraIds.length];
 
-        for (int id = 0; id < nCameras; id++) {
+        int count = 0;
+        for (int id : mCameraIds) {
             DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
                     "test_camera_takePicture");
             reportLog.addValue("camera_id", id, ResultType.NEUTRAL, ResultUnit.NONE);
@@ -172,7 +175,7 @@
                         + ". Max(ms): " + Stat.getMax(cameraTakePictureTimes));
             }
 
-            avgCameraTakePictureTimes[id] = Stat.getAverage(cameraTakePictureTimes);
+            avgCameraTakePictureTimes[count++] = Stat.getAverage(cameraTakePictureTimes);
             reportLog.addValues("camera_open_time", cameraOpenTimes, ResultType.LOWER_BETTER,
                     ResultUnit.MS);
             reportLog.addValues("camera_start_preview_time", startPreviewTimes,
@@ -191,7 +194,7 @@
             reportLog.submit(mInstrumentation);
         }
 
-        if (nCameras != 0) {
+        if (mCameraIds.length != 0) {
             DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
                     "test_camera_takepicture_average");
             reportLog.setSummary("camera_takepicture_average_time_for_all_cameras",
@@ -200,4 +203,4 @@
             reportLog.submit(mInstrumentation);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java b/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
index c7deb5a..6d90f2e 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
@@ -49,15 +49,13 @@
         System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
         mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
         assertNotNull("Unable to get CameraManager", mCameraManager);
-        mCameraIdsUnderTest =
-                CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+        mCameraIdsUnderTest = deriveCameraIdsUnderTest();
         assertNotNull("Unable to get camera ids", mCameraIdsUnderTest);
     }
 
     @Override
     public void tearDown() throws Exception {
-        String[] cameraIdsPostTest =
-                CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+        String[] cameraIdsPostTest = deriveCameraIdsUnderTest();
         assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
         Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIdsUnderTest));
         Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
@@ -67,4 +65,19 @@
                 mCameraIdsUnderTest.length == cameraIdsPostTest.length);
         super.tearDown();
     }
+
+    private String[] deriveCameraIdsUnderTest() throws Exception {
+        String[] idsUnderTest =
+                CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+        assertNotNull("Camera ids shouldn't be null", idsUnderTest);
+        if (mOverrideCameraId != null) {
+            if (Arrays.asList(idsUnderTest).contains(mOverrideCameraId)) {
+                idsUnderTest = new String[]{mOverrideCameraId};
+            } else {
+                idsUnderTest = new String[]{};
+            }
+        }
+
+        return idsUnderTest;
+    }
 }
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
index b2f4c04..047fba5 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
@@ -18,6 +18,7 @@
 
 import android.app.UiAutomation;
 import android.content.Context;
+import android.os.Bundle;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
@@ -42,6 +43,10 @@
     @Parameter(0)
     public boolean mAdoptShellPerm;
 
+    private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+    private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+    protected static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
     @Parameters
     public static Iterable<? extends Object> data() {
         List<Boolean> adoptShellPerm = new ArrayList<Boolean>();
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
index 82df26e..2370023 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
@@ -20,14 +20,22 @@
 import android.hardware.Camera;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
+import android.os.Bundle;
+
+import androidx.test.InstrumentationRegistry;
 
 import java.util.Comparator;
+import java.util.stream.IntStream;
 
 /**
  * Utility class containing helper functions for the Camera CTS tests.
  */
 public class CameraUtils {
 
+    private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+    private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+    public static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
     /**
      * Returns {@code true} if this device only supports {@code LEGACY} mode operation in the
      * Camera2 API for the given camera ID.
@@ -104,4 +112,19 @@
         }
     }
 
+    public static int[] deriveCameraIdsUnderTest() throws Exception {
+        int numberOfCameras = Camera.getNumberOfCameras();
+        int[] cameraIds;
+        if (mOverrideCameraId == null) {
+            cameraIds = IntStream.range(0, numberOfCameras).toArray();
+        } else {
+            int overrideCameraId = Integer.parseInt(mOverrideCameraId);
+            if (overrideCameraId >= 0 && overrideCameraId < numberOfCameras) {
+                cameraIds = new int[]{overrideCameraId};
+            } else {
+                cameraIds = new int[]{};
+            }
+        }
+        return cameraIds;
+    }
 }
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 0f8da29..c95ae9c 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -27,7 +27,7 @@
     <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
     <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
     <application android:label="CtsWindowManagerDeviceTestCases"
             android:requestLegacyExternalStorage="true">
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
index b3ab326..26c5b3a 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
@@ -41,6 +41,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowInsets;
 
 import java.lang.ref.WeakReference;
 
@@ -73,14 +74,13 @@
         view.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-        view.setOnApplyWindowInsetsListener((v, insets) -> {
-            final boolean cutoutExists = (insets.getDisplayCutout() != null);
-            Log.i(TAG, "cutout=" + cutoutExists);
-            TestJournalProvider.putExtras(BroadcastReceiverActivity.this,
-                    bundle -> bundle.putBoolean(EXTRA_CUTOUT_EXISTS, cutoutExists));
-            return insets;
-        });
         setContentView(view);
+
+        WindowInsets insets = getWindowManager().getCurrentWindowMetrics().getWindowInsets();
+        final boolean cutoutExists = (insets.getDisplayCutout() != null);
+        Log.i(TAG, "cutout=" + cutoutExists);
+        TestJournalProvider.putExtras(BroadcastReceiverActivity.this,
+                bundle -> bundle.putBoolean(EXTRA_CUTOUT_EXISTS, cutoutExists));
     }
 
     @Override
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
new file mode 100644
index 0000000..78fe375
--- /dev/null
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
@@ -0,0 +1,66 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.wm.intent.Activities$TaskAffinity1Activity",
+                "package": "android.server.wm.cts",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.wm.intent.Activities$SingleInstanceActivity",
+                "package": "android.server.wm.cts",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
+                                "state": "STOPPED"
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
new file mode 100644
index 0000000..a288a9e
--- /dev/null
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
@@ -0,0 +1,54 @@
+{
+    "setup": {
+        "initialIntents": [
+            {
+                "flags": "FLAG_ACTIVITY_NEW_TASK",
+                "class": "android.server.wm.intent.Activities$SingleTopActivity",
+                "package": "android.server.wm.cts",
+                "startForResult": false
+            }
+        ],
+        "act": [
+            {
+                "flags": "",
+                "class": "android.server.wm.intent.Activities$SingleTopActivity",
+                "package": "android.server.wm.cts",
+                "startForResult": true
+            }
+        ]
+    },
+    "initialState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+            }
+        ]
+    },
+    "endState": {
+        "stacks": [
+            {
+                "tasks": [
+                    {
+                        "activities": [
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
+                                "state": "RESUMED"
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+            }
+        ]
+    }
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
index 6e97377..a80e56b 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
@@ -43,10 +43,6 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
                                 "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
-                                "state": "STOPPED"
                             }
                         ]
                     }
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
index 2ed6023..a288a9e 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
@@ -43,10 +43,6 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
                                 "state": "RESUMED"
-                            },
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "STOPPED"
                             }
                         ]
                     }
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
index 33419d6..be49412 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
@@ -43,15 +43,23 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
                                 "state": "RESUMED"
-                            },
+                            }
+                        ]
+                    }
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+            },
+            {
+                "tasks": [
+                    {
+                        "activities": [
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
                                 "state": "STOPPED"
                             }
                         ]
                     }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+                ]
             }
         ]
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
index f87fad9..edc6f9d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
@@ -16,9 +16,9 @@
 
 package android.server.wm;
 
-import static android.server.wm.WindowManagerState.STATE_RESUMED;
 import static android.server.wm.StateLogger.log;
 import static android.server.wm.StateLogger.logE;
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
 import static android.server.wm.app.Components.FONT_SCALE_ACTIVITY;
 import static android.server.wm.app.Components.FONT_SCALE_NO_RELAUNCH_ACTIVITY;
 import static android.server.wm.app.Components.FontScaleActivity.EXTRA_FONT_ACTIVITY_DPI;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
index 8cf1b47..f8f714c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -56,6 +56,7 @@
 import android.server.wm.CommandSession.ActivitySession;
 import android.server.wm.CommandSession.ActivitySessionClient;
 import android.server.wm.settings.SettingsSession;
+import android.util.DisplayMetrics;
 import android.util.Pair;
 import android.util.Size;
 import android.view.WindowManager;
@@ -168,10 +169,12 @@
         @Nullable
         final Integer overrideDensity;
 
+        final int mDisplayId;
+
         /** Get physical and override display metrics from WM for specified display. */
         public static ReportedDisplayMetrics getDisplayMetrics(int displayId) {
             return new ReportedDisplayMetrics(executeShellCommand(WM_SIZE + " -d " + displayId)
-                            + executeShellCommand(WM_DENSITY + " -d " + displayId));
+                            + executeShellCommand(WM_DENSITY + " -d " + displayId), displayId);
         }
 
         void setDisplayMetrics(final Size size, final int density) {
@@ -193,11 +196,12 @@
         }
 
         private void setSize(final Size size) {
-            executeShellCommand(WM_SIZE + " " + size.getWidth() + "x" + size.getHeight());
+            executeShellCommand(
+                    WM_SIZE + " " + size.getWidth() + "x" + size.getHeight() + " -d " + mDisplayId);
         }
 
         private void setDensity(final int density) {
-            executeShellCommand(WM_DENSITY + " " + density);
+            executeShellCommand(WM_DENSITY + " " + density + " -d " + mDisplayId);
         }
 
         /** Get display size that WM operates with. */
@@ -210,7 +214,8 @@
             return overrideDensity != null ? overrideDensity : physicalDensity;
         }
 
-        private ReportedDisplayMetrics(final String lines) {
+        private ReportedDisplayMetrics(final String lines, int displayId) {
+            mDisplayId = displayId;
             Matcher matcher = PHYSICAL_SIZE.matcher(lines);
             assertTrue("Physical display size must be reported", matcher.find());
             log(matcher.group());
@@ -258,6 +263,16 @@
             return ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
         }
 
+        void changeDisplayMetrics(double sizeRatio, double densityRatio) {
+            final Size originalSize = mInitialDisplayMetrics.physicalSize;
+            final int density = mInitialDisplayMetrics.physicalDensity;
+
+            final Size overrideSize = new Size((int)(originalSize.getWidth() * sizeRatio),
+                    (int)(originalSize.getHeight() * sizeRatio));
+            final int overrideDensity = (int)(density * densityRatio);
+            overrideDisplayMetrics(overrideSize, overrideDensity);
+        }
+
         void overrideDisplayMetrics(final Size size, final int density) {
             mInitialDisplayMetrics.setDisplayMetrics(size, density);
         }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java
new file mode 100644
index 0000000..e9bebce
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+
+@Presubmit
+public class WindowContextTests extends MultiDisplayTestBase {
+    private Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    private Context mContext = mInstrumentation.getTargetContext();
+    private DisplayManager mDisplayManager = mContext.getSystemService(DisplayManager.class);
+
+    @Test
+    public void testWindowContextConfigChanges() {
+        final WindowManagerState.DisplayContent display =  createManagedVirtualDisplaySession()
+                .setSimulateDisplay(true).createDisplay();
+        final Context windowContext = createWindowContext(display.mId);
+        mInstrumentation.runOnMainSync(() -> {
+            final View view = new View(windowContext);
+            WindowManager wm = windowContext.getSystemService(WindowManager.class);
+            wm.addView(view, new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY));
+        });
+        mWmState.computeState();
+
+        final DisplayMetricsSession displayMetricsSession =
+                createManagedDisplayMetricsSession(display.mId);
+
+        displayMetricsSession.changeDisplayMetrics(1.2 /* sizeRatio */, 1.1 /* densityRatio */);
+
+        mWmState.computeState();
+
+        assertDisplayMetricsEquals(displayMetricsSession.getDisplayMetrics(),
+                windowContext.getResources().getDisplayMetrics());
+    }
+
+    private Context createWindowContext(int displayId) {
+        final Display display = mDisplayManager.getDisplay(displayId);
+        return mContext.createDisplayContext(display).createWindowContext(TYPE_APPLICATION_OVERLAY,
+                null /* options */);
+    }
+
+    private void assertDisplayMetricsEquals(ReportedDisplayMetrics expectedMetrics,
+            DisplayMetrics actualMetrics) {
+        assertEquals(expectedMetrics.getSize().getWidth(), actualMetrics.widthPixels);
+        assertEquals(expectedMetrics.getSize().getHeight(), actualMetrics.heightPixels);
+        assertEquals(expectedMetrics.getDensity(), actualMetrics.densityDpi);
+    }
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
index 958279a..1b04e13 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
@@ -18,11 +18,16 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 
 import android.app.Activity;
+import android.graphics.Insets;
+import android.graphics.Point;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
 import android.util.Size;
+import android.view.Display;
+import android.view.DisplayCutout;
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowMetrics;
@@ -34,14 +39,23 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+/**
+ * Tests that verify the behavior of {@link WindowMetrics} and {@link android.app.WindowContext} API
+ *
+ * Build/Install/Run:
+ *     atest CtsWindowManagerDeviceTestCases:WindowMetricsTests
+ */
 @Presubmit
 public class WindowMetricsTests extends WindowManagerTestBase {
 
-    ActivityTestRule<MetricsActivity> mMetricsActivity =
+    private ActivityTestRule<MetricsActivity> mMetricsActivity =
             new ActivityTestRule<>(MetricsActivity.class);
 
     @Test
-    public void test_metrics() {
+    public void testMetricsSanity() {
+        // TODO(b/149668895): handle device with cutout.
+        assumeFalse(hasDisplayCutout());
+
         final MetricsActivity activity = mMetricsActivity.launchActivity(null);
         activity.waitForLayout();
 
@@ -57,7 +71,58 @@
                 activity.mOnCreateCurrentMetrics.getWindowInsets().getStableInsets());
         assertEquals(activity.mOnLayoutInsets.getDisplayCutout(),
                 activity.mOnCreateCurrentMetrics.getWindowInsets().getDisplayCutout());
+    }
 
+    @Test
+    public void testMetricsMatchesDisplay() {
+        final MetricsActivity activity = mMetricsActivity.launchActivity(null);
+        activity.waitForLayout();
+
+        final Display display = activity.getDisplay();
+
+        // Check window size
+        final Point displaySize = new Point();
+        display.getSize(displaySize);
+        final WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();
+        final Size size = getLegacySize(windowMetrics);
+        assertEquals("Reported display width must match window width",
+                displaySize.x, size.getWidth());
+        assertEquals("Reported display height must match window height",
+                displaySize.y, size.getHeight());
+
+        // Check max window size
+        final Point realDisplaySize = new Point();
+        display.getRealSize(realDisplaySize);
+        final WindowMetrics maxWindowMetrics = activity.getWindowManager()
+                .getMaximumWindowMetrics();
+        assertEquals("Reported real display width must match max window size",
+                realDisplaySize.x, maxWindowMetrics.getSize().getWidth());
+        assertEquals("Reported real display height must match max window size",
+                realDisplaySize.y, maxWindowMetrics.getSize().getHeight());
+    }
+
+    private static Size getLegacySize(WindowMetrics windowMetrics) {
+        WindowInsets windowInsets = windowMetrics.getWindowInsets();
+        final Insets insetsWithCutout = getProperInsetsWithCutout(windowInsets.getStableInsets(),
+                windowInsets.getDisplayCutout());
+        final int insetsInWidth = insetsWithCutout.left + insetsWithCutout.right;
+        final int insetsInHeight = insetsWithCutout.top + insetsWithCutout.bottom;
+
+        Size size = windowMetrics.getSize();
+        return new Size(size.getWidth() - insetsInWidth, size.getHeight() - insetsInHeight);
+    }
+
+    private static Insets getProperInsetsWithCutout(Insets stableInsets, DisplayCutout cutout) {
+        final Insets excludingStatusBar = Insets.of(stableInsets.left, 0,
+                stableInsets.right, stableInsets.bottom);
+        if (cutout == null) {
+            return excludingStatusBar;
+        } else {
+            final Insets unionInsetsWithCutout = Insets.max(excludingStatusBar,
+                    Insets.of(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
+                            cutout.getSafeInsetRight(), cutout.getSafeInsetBottom()));
+            return unionInsetsWithCutout;
+        }
     }
 
     public static class MetricsActivity extends Activity implements View.OnLayoutChangeListener {
@@ -78,7 +143,6 @@
             getWindow().getDecorView().addOnLayoutChangeListener(this);
         }
 
-
         @Override
         public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
                 int oldTop, int oldRight, int oldBottom) {
@@ -88,7 +152,7 @@
             mLayoutLatch.countDown();
         }
 
-        public void waitForLayout() {
+        void waitForLayout() {
             try {
                 assertTrue("timed out waiting for activity to layout",
                         mLayoutLatch.await(4, TimeUnit.SECONDS));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
index 9ba003c..e4cb869 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
@@ -17,6 +17,7 @@
 package android.server.wm.intent;
 
 import android.app.Activity;
+import android.os.Bundle;
 
 /**
  * A collection of activities with various launch modes used in the intent tests.
@@ -27,60 +28,68 @@
  */
 public class Activities {
 
-    public static class TrackerActivity extends Activity {
+    private static class BaseActivity extends Activity {
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setTitle(getClass().getSimpleName());
+        }
     }
 
-    public static class RegularActivity extends Activity {
+    public static class TrackerActivity extends BaseActivity {
     }
 
-    public static class SingleTopActivity extends Activity {
+    public static class RegularActivity extends BaseActivity {
     }
 
-    public static class SingleInstanceActivity extends Activity {
+    public static class SingleTopActivity extends BaseActivity {
     }
 
-    public static class SingleInstanceActivity2 extends Activity {
+    public static class SingleInstanceActivity extends BaseActivity {
     }
 
-    public static class SingleTaskActivity extends Activity {
+    public static class SingleInstanceActivity2 extends BaseActivity {
     }
 
-    public static class SingleTaskActivity2 extends Activity {
+    public static class SingleTaskActivity extends BaseActivity {
     }
 
-    public static class TaskAffinity1Activity extends Activity {
+    public static class SingleTaskActivity2 extends BaseActivity {
     }
 
-    public static class TaskAffinity1Activity2 extends Activity {
+    public static class TaskAffinity1Activity extends BaseActivity {
     }
 
-    public static class TaskAffinity2Activity extends Activity {
+    public static class TaskAffinity1Activity2 extends BaseActivity {
     }
 
-    public static class TaskAffinity3Activity extends Activity {
+    public static class TaskAffinity2Activity extends BaseActivity {
     }
 
-    public static class ClearTaskOnLaunchActivity extends Activity {
+    public static class TaskAffinity3Activity extends BaseActivity {
     }
 
-    public static class DocumentLaunchIntoActivity extends Activity {
+    public static class ClearTaskOnLaunchActivity extends BaseActivity {
     }
 
-    public static class DocumentLaunchAlwaysActivity extends Activity {
+    public static class DocumentLaunchIntoActivity extends BaseActivity {
     }
 
-    public static class DocumentLaunchNeverActivity extends Activity {
+    public static class DocumentLaunchAlwaysActivity extends BaseActivity {
     }
 
-    public static class NoHistoryActivity extends Activity {
+    public static class DocumentLaunchNeverActivity extends BaseActivity {
     }
 
-    public static class LauncherActivity extends Activity {
+    public static class NoHistoryActivity extends BaseActivity {
     }
 
-    public static class RelinquishTaskIdentityActivity extends Activity {
+    public static class LauncherActivity extends BaseActivity {
     }
 
-    public static class TaskAffinity1RelinquishTaskIdentityActivity extends Activity {
+    public static class RelinquishTaskIdentityActivity extends BaseActivity {
+    }
+
+    public static class TaskAffinity1RelinquishTaskIdentityActivity extends BaseActivity {
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
index 9e1d67a..950047d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
@@ -264,6 +264,11 @@
 
         if (activity == null) {
             return activityContext;
+        } else if (startForResult && activityContext == activity) {
+            // The result might have send back to caller activity and forced the caller activity
+            // to resumed again, before the started activity actually resumed. Just wait for idle
+            // for that case.
+            getInstrumentation().waitForIdleSync();
         } else {
             waitAndAssertActivityLaunched(activity, intent);
         }
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index ecbe048..6142b9e 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -43,7 +43,6 @@
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.KeyEvent;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -64,7 +63,6 @@
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.CallSuper;
@@ -75,6 +73,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -637,7 +636,7 @@
     @GuardedBy("this")
     private boolean mSuggestionViewVisible = false;
 
-    public InlineSuggestionsRequest onCreateInlineSuggestionsRequest() {
+    public InlineSuggestionsRequest onCreateInlineSuggestionsRequest(Bundle uiExtras) {
         Log.d(TAG, "onCreateInlineSuggestionsRequest() called");
         final ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
         presentationSpecs.add(new InlinePresentationSpec.Builder(new Size(100, 100),
@@ -694,21 +693,30 @@
         Log.d(TAG, "updateSuggestionViews() called on " + suggestionViews.length + " views");
         mSuggestionViews = Arrays.asList(suggestionViews);
         mSuggestionViewSizes = Arrays.asList(sizes);
-        updateInlineSuggestionVisibility(true, true);
+        final boolean visible = !mSuggestionViews.isEmpty();
+        updateInlineSuggestionVisibility(visible, true);
         onSuggestionViewUpdated();
     }
 
     private void onInlineSuggestionsResponseInternal(InlineSuggestionsResponse response) {
-        Log.d(TAG, "onInlineSuggestionsResponseInternal() called. Suggestion="
-                + response.getInlineSuggestions().size());
-
+        if (response == null || response.getInlineSuggestions() == null) {
+            Log.w(TAG, "onInlineSuggestionsResponseInternal() null response/suggestions");
+            return;
+        }
         final List<InlineSuggestion> inlineSuggestions = response.getInlineSuggestions();
         final int totalSuggestionsCount = inlineSuggestions.size();
+        Log.d(TAG, "onInlineSuggestionsResponseInternal() called. Suggestion="
+                + totalSuggestionsCount);
+
+        if (totalSuggestionsCount == 0) {
+            updateSuggestionViews(new View[]{} , new Size[]{});
+        }
+
         final AtomicInteger suggestionsCount = new AtomicInteger(totalSuggestionsCount);
         final View[] suggestionViews = new View[totalSuggestionsCount];
         final Size[] sizes = new Size[totalSuggestionsCount];
 
-        for (int i=0; i < totalSuggestionsCount; i++) {
+        for (int i = 0; i < totalSuggestionsCount; i++) {
             final int index = i;
             InlineSuggestion inlineSuggestion = inlineSuggestions.get(index);
             Size size = inlineSuggestion.getInfo().getPresentationSpec().getMaxSize();
diff --git a/tests/location/location_fine/AndroidManifest.xml b/tests/location/location_fine/AndroidManifest.xml
index 01fe459..0804333 100644
--- a/tests/location/location_fine/AndroidManifest.xml
+++ b/tests/location/location_fine/AndroidManifest.xml
@@ -27,6 +27,7 @@
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="android.location.cts.fine"
diff --git a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
index 802aa2c..b7853e8 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
@@ -22,6 +22,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.platform.test.annotations.AppModeFull;
@@ -33,6 +34,7 @@
 import android.test.AndroidTestCase;
 
 import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.PollingCheck;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -76,12 +78,35 @@
     }
 
     @CddTest(requirement = "7.4.2/C-2-1")
-    public void testWifiScanningSettings() throws PackageManager.NameNotFoundException {
+    public void testWifiScanningSettings() throws Exception {
         if (isTv()) {
             return;
         }
         launchScanningSettings();
-        toggleSettingAndVerify(WIFI_SCANNING_TITLE_RES, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE);
+
+        final Resources res = mPackageManager.getResourcesForApplication(SETTINGS_PACKAGE);
+        final int resId = res.getIdentifier(WIFI_SCANNING_TITLE_RES, "string", SETTINGS_PACKAGE);
+        final UiObject2 pref = mDevice.findObject(By.text(res.getString(resId)));
+
+        final WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
+
+        final boolean checked = wifiManager.isScanAlwaysAvailable();
+
+        // Click the preference to toggle the setting.
+        pref.click();
+        PollingCheck.check(
+                "Scan Always Available wasn't toggled from " + checked + " to " + !checked,
+                TIMEOUT,
+                () -> !checked == wifiManager.isScanAlwaysAvailable()
+        );
+
+        // Click the preference again to toggle the setting back.
+        pref.click();
+        PollingCheck.check(
+                "Scan Always Available wasn't toggled from " + !checked + " to " + checked,
+                TIMEOUT,
+                () -> checked == wifiManager.isScanAlwaysAvailable()
+        );
     }
 
     @CddTest(requirement = "7.4.3/C-4-1")
diff --git a/tests/media/Android.bp b/tests/media/Android.bp
index b813fb2..adcf3de 100644
--- a/tests/media/Android.bp
+++ b/tests/media/Android.bp
@@ -24,6 +24,7 @@
         "android.test.runner.stubs",
         "android.test.base.stubs",
     ],
+    jni_uses_platform_apis: true,
     jni_libs: [
         "libctsmediav2muxer_jni",
         "libctsmediav2extractor_jni",
diff --git a/tests/tests/dynamic_linker/Android.bp b/tests/tests/dynamic_linker/Android.bp
index 76b6603..ee88e21 100644
--- a/tests/tests/dynamic_linker/Android.bp
+++ b/tests/tests/dynamic_linker/Android.bp
@@ -14,6 +14,7 @@
 
 cc_test_library {
     name: "libdynamiclinker_native_lib_a",
+    sdk_version: "current",
     srcs: ["native_lib_a.cpp"],
     cflags: [
         "-Wall",
@@ -27,6 +28,7 @@
 
 cc_test_library {
     name: "libdynamiclinker_native_lib_b",
+    sdk_version: "current",
     srcs: ["native_lib_b.cpp"],
     cflags: [
         "-Wall",
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
index 3f8c011..0374082 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
@@ -29,7 +29,6 @@
 import com.android.compatibility.common.util.CddTest;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -70,7 +69,6 @@
     }
 
     @CddTest(requirement = "7.1.4.2/C-1-8")
-    @Ignore("b/149464764: Test disabled until certain targets get the new feature flag.")
     @Test
     public void testVulkanDeqpLevel() {
         if (mVulkanHardwareVersion.version >= VULKAN_1_0) {
diff --git a/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
index 5d9d7aa..527dee5 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
@@ -18,8 +18,6 @@
 
 import android.security.keystore.KeyProperties;
 
-import org.junit.Test;
-
 import java.security.AlgorithmParameters;
 
 import javax.crypto.Cipher;
@@ -31,18 +29,30 @@
     final int[] TEST_MESSAGE_SIZES = {1 << 6, 1 << 10, 1 << 17};
 
     public void testDESede_CBC_NoPadding() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         testDesCipher("DESede/CBC/NoPadding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
     }
 
     public void testDESede_CBC_PKCS7Padding() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         testDesCipher("DESede/CBC/PKCS7Padding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
     }
 
     public void testDESede_ECB_NoPadding() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         testDesCipher("DESede/ECB/NoPadding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
     }
 
     public void testDESede_ECB_PKCS7Padding() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         testDesCipher("DESede/ECB/PKCS7Padding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
     }
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
index 195d573..0d9d627 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
@@ -18,13 +18,14 @@
 
 import android.security.keystore.KeyProperties;
 
-import org.junit.Test;
-
 public class DesKeyGenPerformanceTest extends PerformanceTestBase {
 
     final int[] SUPPORTED_DES_KEY_SIZES = {168};
 
     public void testDesKeyGen() throws Exception {
+        if (!TestUtils.supports3DES()) {
+            return;
+        }
         for (int keySize : SUPPORTED_DES_KEY_SIZES) {
             measure(
                     new KeystoreSecretKeyGenMeasurable(
diff --git a/tests/tests/libthermalndk/Android.bp b/tests/tests/libthermalndk/Android.bp
new file mode 100644
index 0000000..2b7d126
--- /dev/null
+++ b/tests/tests/libthermalndk/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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: "CtsThermalTestCases",
+    defaults: ["cts_defaults"],
+    compile_multilib: "both",
+    static_libs: [
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+    ],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    jni_libs: [
+        "libctsthermal_jni",
+    ],
+    srcs: ["src/**/*.java"],
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    sdk_version: "test_current",
+}
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml b/tests/tests/libthermalndk/AndroidManifest.xml
similarity index 68%
copy from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
copy to tests/tests/libthermalndk/AndroidManifest.xml
index a649209..eb6eb22 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
+++ b/tests/tests/libthermalndk/AndroidManifest.xml
@@ -14,13 +14,18 @@
  * 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.blob.helper">
+        package="android.thermal.cts">
+
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-
-    <instrumentation
-            android:name="androidx.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.cts.blob.helper"  />
-</manifest>
\ No newline at end of file
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+            android:targetPackage="android.thermal.cts"
+            android:label="CTS Thermal tests of android.thermal" >
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/libthermalndk/AndroidTest.xml b/tests/tests/libthermalndk/AndroidTest.xml
new file mode 100644
index 0000000..e4ab0ac
--- /dev/null
+++ b/tests/tests/libthermalndk/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 Thermal test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsThermalTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.thermal.cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/libthermalndk/OWNERS b/tests/tests/libthermalndk/OWNERS
new file mode 100644
index 0000000..1c617ec
--- /dev/null
+++ b/tests/tests/libthermalndk/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 46788
+michaelwr@google.com
+lzye@google.com
diff --git a/tests/tests/libthermalndk/jni/Android.bp b/tests/tests/libthermalndk/jni/Android.bp
new file mode 100644
index 0000000..9f95e7f
--- /dev/null
+++ b/tests/tests/libthermalndk/jni/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test_library {
+    name: "libctsthermal_jni",
+    srcs: [
+        "NativeThermalTest.cpp",
+    ],
+    shared_libs: [
+        "libandroid",
+        "liblog",
+        "libbase",
+    ],
+    stl: "libc++_static",
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    gtest: false,
+}
diff --git a/tests/tests/libthermalndk/jni/NativeThermalTest.cpp b/tests/tests/libthermalndk/jni/NativeThermalTest.cpp
new file mode 100644
index 0000000..913a8ae
--- /dev/null
+++ b/tests/tests/libthermalndk/jni/NativeThermalTest.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NativeThermalTest"
+
+#include <condition_variable>
+#include <jni.h>
+#include <mutex>
+#include <optional>
+#include <thread>
+#include <inttypes.h>
+#include <time.h>
+#include <unistd.h>
+#include <vector>
+
+#include <android/thermal.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <log/log.h>
+#include <sys/stat.h>
+#include <utils/Errors.h>
+
+using namespace android;
+using namespace std::chrono_literals;
+using android::base::StringPrintf;
+
+struct AThermalTestContext {
+    AThermalManager *mThermalMgr;
+    std::mutex mMutex;
+    std::condition_variable mCv;
+    std::vector<AThermalStatus> mListenerStatus GUARDED_BY(mMutex);
+};
+
+static jclass    gNativeThermalTest_class;
+static jmethodID gNativeThermalTest_thermalOverrideMethodID;
+
+int onStatusChange(void *data, AThermalStatus status) {
+    AThermalTestContext *ctx = static_cast<AThermalTestContext *>(data);
+    if (ctx == nullptr) {
+        return BAD_VALUE;
+    } else {
+        std::lock_guard<std::mutex> guard(ctx->mMutex);
+        ctx->mListenerStatus.push_back(status);
+        ctx->mCv.notify_all();
+    }
+    return OK;
+}
+
+static inline void setThermalStatusOverride(JNIEnv* env, jobject obj, int32_t level) {
+    env->CallVoidMethod(obj, gNativeThermalTest_thermalOverrideMethodID, level);
+}
+
+static inline jstring returnJString(JNIEnv *env, std::optional<std::string> result) {
+    if (result.has_value()) {
+        return env->NewStringUTF(result.value().c_str());
+    } else {
+        return env->NewStringUTF("");
+    }
+}
+
+static std::optional<std::string> testGetCurrentThermalStatus(
+                                        JNIEnv *env, jobject obj, int32_t level) {
+    AThermalTestContext ctx;
+
+    ctx.mThermalMgr = AThermal_acquireManager();
+    if (ctx.mThermalMgr == nullptr) {
+        return "AThermal_acquireManager failed";
+    }
+
+    setThermalStatusOverride(env, obj, level);
+    AThermalStatus thermalStatus = AThermal_getCurrentThermalStatus(ctx.mThermalMgr);
+    if (thermalStatus == ATHERMAL_STATUS_ERROR) {
+        return "getCurrentThermalStatus returns ATHERMAL_STATUS_ERROR";
+    }
+    // Verify the current thermal status is same as override
+    if (thermalStatus != static_cast<AThermalStatus>(level)) {
+        return StringPrintf("getCurrentThermalStatus %" PRId32 " != override %" PRId32 ".",
+                            thermalStatus, level);
+    }
+
+    AThermal_releaseManager(ctx.mThermalMgr);
+    return std::nullopt;
+}
+
+static jstring nativeTestGetCurrentThermalStatus(JNIEnv *env, jobject obj, jint level) {
+    return returnJString(env, testGetCurrentThermalStatus(env, obj, static_cast<int32_t>(level)));
+}
+
+static std::optional<std::string> testRegisterThermalStatusListener(JNIEnv *env, jobject obj) {
+    AThermalTestContext ctx;
+    std::unique_lock<std::mutex> lock(ctx.mMutex);
+
+    ctx.mThermalMgr = AThermal_acquireManager();
+    if (ctx.mThermalMgr == nullptr) {
+        return "AThermal_acquireManager failed";
+    }
+
+    // Register a listener with valid callback
+    int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != 0) {
+        return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+                    strerror(ret));
+    }
+
+    // Expect the callback after registration
+    if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+        return "Listener callback should be called after registration";
+    }
+
+    // Verify the current thermal status is same as listener callback
+    auto thermalStatus = AThermal_getCurrentThermalStatus(ctx.mThermalMgr);
+    auto listenerStatus = ctx.mListenerStatus.back();
+    if (thermalStatus != listenerStatus) {
+        return StringPrintf("thermalStatus %" PRId32 " != Listener status %" PRId32 ".",
+                            thermalStatus, listenerStatus);
+    }
+
+    // Change override level and verify the listener callback
+    for (int32_t level = ATHERMAL_STATUS_LIGHT; level <= ATHERMAL_STATUS_SHUTDOWN; level++) {
+        setThermalStatusOverride(env, obj, level);
+        if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+            return StringPrintf("Listener callback timeout at level %" PRId32, level);
+        }
+        auto overrideStatus = static_cast<AThermalStatus>(level);
+        auto listenerStatus = ctx.mListenerStatus.back();
+        if (listenerStatus != overrideStatus) {
+            return StringPrintf("Listener thermalStatus%" PRId32 " != override %" PRId32 ".",
+                            listenerStatus, overrideStatus);
+        }
+    }
+
+    // Unregister listener
+    ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != 0) {
+        return StringPrintf("AThermal_unregisterThermalStatusListener failed: %s",
+                    strerror(ret));
+    }
+
+    AThermal_releaseManager(ctx.mThermalMgr);
+    return std::nullopt;
+}
+
+static jstring nativeTestRegisterThermalStatusListener(JNIEnv *env, jobject obj) {
+    return returnJString(env, testRegisterThermalStatusListener(env, obj));
+}
+
+static std::optional<std::string> testThermalStatusRegisterNullListener() {
+    AThermalTestContext ctx;
+
+    ctx.mThermalMgr = AThermal_acquireManager();
+    if (ctx.mThermalMgr == nullptr) {
+        return StringPrintf("AThermal_acquireManager failed");
+    }
+
+    // Register a listener with null callback
+    int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, nullptr, &ctx);
+    if (ret != EINVAL) {
+        return "AThermal_registerThermalStatusListener should fail with null callback";
+    }
+
+    // Register a listener with null data
+    ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != 0) {
+        return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+                    strerror(ret));
+    }
+
+    // Unregister listener with null callback and null data
+    ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, nullptr, nullptr);
+    if (ret != EINVAL) {
+        return "AThermal_unregisterThermalStatusListener should fail with null listener";
+    }
+
+    AThermal_releaseManager(ctx.mThermalMgr);
+    return std::nullopt;
+}
+
+static jstring nativeTestThermalStatusRegisterNullListener(JNIEnv *env, jobject) {
+    return returnJString(env, testThermalStatusRegisterNullListener());
+}
+
+static std::optional<std::string> testThermalStatusListenerDoubleRegistration
+                                                        (JNIEnv *env, jobject obj) {
+    AThermalTestContext ctx;
+    std::unique_lock<std::mutex> lock(ctx.mMutex);
+
+    ctx.mThermalMgr = AThermal_acquireManager();
+    if (ctx.mThermalMgr == nullptr) {
+        return "AThermal_acquireManager failed";
+    }
+
+    // Register a listener with valid callback
+    int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != 0) {
+        return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+                    strerror(ret));
+    }
+
+    // Register the listener again with same callback and data
+    ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != EINVAL) {
+        return "Register should fail as listener already registered";
+    }
+
+    // Register a listener with same callback but null data
+    ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, nullptr);
+    if (ret != 0) {
+        return StringPrintf("Register listener with null data failed: %s", strerror(ret));
+    }
+
+    // Expect listener callback
+    if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+        return "Thermal listener callback timeout";
+    }
+
+    // Unregister listener
+    ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != 0) {
+        return StringPrintf("AThermal_unregisterThermalStatusListener failed: %s",
+                    strerror(ret));
+    }
+
+    for (int32_t level = ATHERMAL_STATUS_LIGHT; level <= ATHERMAL_STATUS_SHUTDOWN; level++) {
+        setThermalStatusOverride(env, obj, level);
+        // Expect no listener callback
+        if (ctx.mCv.wait_for(lock, 1s) != std::cv_status::timeout) {
+            return "Thermal listener got callback after unregister.";
+        }
+    }
+
+    // Unregister listener already unregistered
+    ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+    if (ret != EINVAL) {
+        return "Unregister should fail with listener already unregistered";
+    }
+
+    AThermal_releaseManager(ctx.mThermalMgr);
+    return std::nullopt;
+}
+
+static jstring nativeTestThermalStatusListenerDoubleRegistration(JNIEnv *env, jobject obj) {
+    return returnJString(env, testThermalStatusListenerDoubleRegistration(env, obj));
+}
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv* env;
+    const JNINativeMethod methodTable[] = {
+        {"nativeTestGetCurrentThermalStatus", "(I)Ljava/lang/String;",
+         (void*)nativeTestGetCurrentThermalStatus},
+        {"nativeTestRegisterThermalStatusListener", "()Ljava/lang/String;",
+         (void*)nativeTestRegisterThermalStatusListener},
+        {"nativeTestThermalStatusRegisterNullListener", "()Ljava/lang/String;",
+         (void*)nativeTestThermalStatusRegisterNullListener},
+        {"nativeTestThermalStatusListenerDoubleRegistration", "()Ljava/lang/String;",
+         (void*)nativeTestThermalStatusListenerDoubleRegistration},
+    };
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return JNI_ERR;
+    }
+    gNativeThermalTest_class = env->FindClass("android/thermal/cts/NativeThermalTest");
+    gNativeThermalTest_thermalOverrideMethodID =
+                env->GetMethodID(gNativeThermalTest_class, "setOverrideStatus", "(I)V");
+    if (gNativeThermalTest_thermalOverrideMethodID == nullptr) {
+        return JNI_ERR;
+    }
+    if (env->RegisterNatives(gNativeThermalTest_class, methodTable,
+            sizeof(methodTable) / sizeof(JNINativeMethod)) != JNI_OK) {
+        return JNI_ERR;
+    }
+    return JNI_VERSION_1_6;
+}
diff --git a/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java b/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java
new file mode 100644
index 0000000..ab6d518
--- /dev/null
+++ b/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.thermal.cts;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.support.test.uiautomator.UiDevice;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import com.google.common.base.Strings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Tests native thermal API for get current thermal status, register and unregister
+ * thermal status listeners.
+ */
+@RunWith(AndroidJUnit4.class)
+public class NativeThermalTest {
+    private UiDevice mUiDevice;
+    private Executor mExec = Executors.newSingleThreadExecutor();
+
+    private native String nativeTestGetCurrentThermalStatus(int level);
+    private native String nativeTestRegisterThermalStatusListener();
+    private native String nativeTestThermalStatusRegisterNullListener();
+    private native String nativeTestThermalStatusListenerDoubleRegistration();
+
+    @Before
+    public void setUp() throws Exception {
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mUiDevice.executeShellCommand("cmd thermalservice reset");
+    }
+
+    /**
+     * Helper function to set override status
+     */
+    public void setOverrideStatus (int level)  throws Exception {
+        mUiDevice.executeShellCommand("cmd thermalservice override-status " + level);
+    }
+
+    /**
+     * Confirm that we can get thermal status.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testGetCurrentThermalStatus() throws Exception {
+        for (int level = PowerManager.THERMAL_STATUS_NONE;
+                level < PowerManager.THERMAL_STATUS_SHUTDOWN; level++) {
+            final String failureMessage = nativeTestGetCurrentThermalStatus(level);
+            if (!Strings.isNullOrEmpty(failureMessage)) {
+                fail(failureMessage);
+            }
+        }
+    }
+
+    /**
+     * Confirm that we can register thermal status listener and get callback.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testRegisterThermalStatusListener() throws Exception {
+        final String failureMessage = nativeTestRegisterThermalStatusListener();
+        if (!Strings.isNullOrEmpty(failureMessage)) {
+            fail(failureMessage);
+        }
+    }
+
+    /**
+     * Confirm that register null thermal status listener fails with error.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testThermalStatusRegisterNullListener() throws Exception {
+        final String failureMessage = nativeTestThermalStatusRegisterNullListener();
+        if (!Strings.isNullOrEmpty(failureMessage)) {
+            fail(failureMessage);
+        }
+    }
+
+    /**
+     * Confirm that double register and unregister same listener fails with error.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testThermalStatusListenerDoubleRegistration() throws Exception {
+        final String failureMessage = nativeTestThermalStatusListenerDoubleRegistration();
+        if (!Strings.isNullOrEmpty(failureMessage)) {
+            fail(failureMessage);
+        }
+    }
+
+    static {
+        System.loadLibrary("ctsthermal_jni");
+    }
+}
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index a7727b1..1bec10d 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -143,7 +143,7 @@
             android:foregroundServiceType="mediaProjection"
             android:enabled="true">
         </service>
-        <service android:name=".SampleMediaRoute2ProviderService"
+        <service android:name=".StubMediaRoute2ProviderService"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.media.MediaRoute2ProviderService" />
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 90125d0..193345a 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -2532,4 +2532,104 @@
             }
         }
     }
+
+    /**
+     * Test if flushing early in the playback does not prevent client from getting the
+     * latest configuration. Empirically, this happens most often when the
+     * codec is flushed after the first buffer is queued, so this test walks
+     * through the scenario.
+     */
+    public void testFlushAfterFirstBuffer() throws Exception {
+        for (int i = 0; i < 100; ++i) {
+            doFlushAfterFirstBuffer();
+        }
+    }
+
+    private void doFlushAfterFirstBuffer() throws Exception {
+        MediaExtractor extractor = null;
+        MediaCodec codec = null;
+
+        try {
+            MediaFormat newFormat = null;
+            extractor = getMediaExtractorForMimeType(
+                    R.raw.noise_2ch_48khz_aot29_dr_sbr_sig2_mp4, "audio/");
+            int trackIndex = extractor.getSampleTrackIndex();
+            MediaFormat format = extractor.getTrackFormat(trackIndex);
+            codec = createCodecByType(
+                    format.getString(MediaFormat.KEY_MIME), false /* isEncoder */);
+            codec.configure(format, null, null, 0);
+            codec.start();
+            int firstInputIndex = codec.dequeueInputBuffer(0);
+            while (firstInputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                firstInputIndex = codec.dequeueInputBuffer(5000);
+            }
+            assertTrue(firstInputIndex >= 0);
+            extractor.readSampleData(codec.getInputBuffer(firstInputIndex), 0);
+            codec.queueInputBuffer(
+                    firstInputIndex, 0, Math.toIntExact(extractor.getSampleSize()),
+                    extractor.getSampleTime(), extractor.getSampleFlags());
+            // Don't advance, so the first buffer will be read again after flush
+            codec.flush();
+            ByteBuffer csd = format.getByteBuffer("csd-0");
+            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
+            // We don't need to decode many frames
+            int numFrames = 10;
+            boolean eos = false;
+            while (!eos) {
+                if (numFrames > 0) {
+                    int inputIndex = codec.dequeueInputBuffer(0);
+                    if (inputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                        inputIndex = codec.dequeueInputBuffer(5000);
+                    }
+                    if (inputIndex >= 0) {
+                        ByteBuffer inputBuffer = codec.getInputBuffer(inputIndex);
+                        if (csd != null) {
+                            inputBuffer.clear();
+                            inputBuffer.put(csd);
+                            codec.queueInputBuffer(
+                                    inputIndex, 0, inputBuffer.position(), 0,
+                                    MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
+                            csd = null;
+                        } else {
+                            int size = extractor.readSampleData(inputBuffer, 0);
+                            if (size <= 0) {
+                                break;
+                            }
+                            int flags = extractor.getSampleFlags();
+                            --numFrames;
+                            if (numFrames <= 0) {
+                                flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+                            }
+                            codec.queueInputBuffer(
+                                    inputIndex, 0, size, extractor.getSampleTime(), flags);
+                            extractor.advance();
+                        }
+                    }
+                }
+
+                int outputIndex = codec.dequeueOutputBuffer(bufferInfo, 0);
+                if (outputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    outputIndex = codec.dequeueOutputBuffer(bufferInfo, 5000);
+                }
+                if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    newFormat = codec.getOutputFormat();
+                } else if (outputIndex >= 0) {
+                    if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                        eos = true;
+                    }
+                    codec.releaseOutputBuffer(outputIndex, false);
+                }
+            }
+            assertNotNull(newFormat);
+            assertEquals(48000, newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
+        } finally {
+            if (extractor != null) {
+                extractor.release();
+            }
+            if (codec != null) {
+                codec.stop();
+                codec.release();
+            }
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
index 98f92d9..773aede 100644
--- a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
@@ -17,12 +17,12 @@
 package android.media.cts;
 
 import static android.media.cts.MediaRouter2Test.releaseControllers;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SPECIAL;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID1;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID2;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SPECIAL;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID1;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID2;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,7 +40,7 @@
 import android.media.MediaRouter2.TransferCallback;
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
-import android.media.cts.SampleMediaRoute2ProviderService.Proxy;
+import android.media.cts.StubMediaRoute2ProviderService.Proxy;
 import android.os.Bundle;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.LargeTest;
@@ -66,14 +66,14 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "The system should be able to bind to SampleMediaRoute2ProviderService")
+@AppModeFull(reason = "The system should be able to bind to StubMediaRoute2ProviderService")
 @LargeTest
 public class MediaRoute2ProviderServiceTest {
     private static final String TAG = "MR2ProviderServiceTest";
     Context mContext;
     private MediaRouter2 mRouter2;
     private Executor mExecutor;
-    private SampleMediaRoute2ProviderService mService;
+    private StubMediaRoute2ProviderService mService;
 
     private static final int TIMEOUT_MS = 5000;
 
@@ -93,8 +93,8 @@
         new PollingCheck(TIMEOUT_MS) {
             @Override
             protected boolean check() {
-                SampleMediaRoute2ProviderService service =
-                        SampleMediaRoute2ProviderService.getInstance();
+                StubMediaRoute2ProviderService service =
+                        StubMediaRoute2ProviderService.getInstance();
                 if (service != null) {
                     mService = service;
                     return true;
@@ -121,7 +121,7 @@
                 SESSION_ID_1, "" /* clientPackageName */)
                 .addSelectedRoute(ROUTE_ID1)
                 .build();
-        mService.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
+        mService.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_NONE);
         assertEquals(1, mService.getAllSessionInfo().size());
         assertEquals(sessionInfo1, mService.getAllSessionInfo().get(0));
         assertEquals(sessionInfo1, mService.getSessionInfo(SESSION_ID_1));
@@ -132,7 +132,7 @@
                 .addSelectedRoute(ROUTE_ID2)
                 .build();
         mService.notifySessionCreated(
-                sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
+                sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_NONE);
         assertEquals(2, mService.getAllSessionInfo().size());
         assertEquals(sessionInfo2, mService.getSessionInfo(SESSION_ID_2));
 
@@ -288,7 +288,7 @@
         // Now test all session-related callbacks.
         setProxy(new Proxy() {
             @Override
-            public void onCreateSession(String packageName, String routeId, long requestId,
+            public void onCreateSession(long requestId, String packageName, String routeId,
                     Bundle sessionHints) {
                 assertEquals(mContext.getPackageName(), packageName);
                 assertEquals(ROUTE_ID1, routeId);
@@ -307,7 +307,7 @@
             }
 
             @Override
-            public void onSelectRoute(String sessionId, String routeId) {
+            public void onSelectRoute(long requestId, String sessionId, String routeId) {
                 assertEquals(SESSION_ID_1, sessionId);
                 assertEquals(ROUTE_ID4_TO_SELECT_AND_DESELECT, routeId);
 
@@ -322,7 +322,7 @@
             }
 
             @Override
-            public void onDeselectRoute(String sessionId, String routeId) {
+            public void onDeselectRoute(long requestId, String sessionId, String routeId) {
                 assertEquals(SESSION_ID_1, sessionId);
                 assertEquals(ROUTE_ID4_TO_SELECT_AND_DESELECT, routeId);
 
@@ -337,7 +337,7 @@
             }
 
             @Override
-            public void onTransferToRoute(String sessionId, String routeId) {
+            public void onTransferToRoute(long requestId, String sessionId, String routeId) {
                 assertEquals(SESSION_ID_1, sessionId);
                 assertEquals(ROUTE_ID5_TO_TRANSFER_TO, routeId);
 
@@ -353,7 +353,7 @@
             }
 
             @Override
-            public void onReleaseSession(String sessionId) {
+            public void onReleaseSession(long requestId, String sessionId) {
                 assertEquals(SESSION_ID_1, sessionId);
                 mService.notifySessionReleased(sessionId);
                 onReleaseSessionLatch.countDown();
@@ -455,7 +455,7 @@
         CountDownLatch onCreateSessionLatch = new CountDownLatch(1);
         setProxy(new Proxy() {
             @Override
-            public void onCreateSession(String packageName, String routeId, long requestId,
+            public void onCreateSession(long requestId, String packageName, String routeId,
                     Bundle sessionHints) {
                 assertEquals(mContext.getPackageName(), packageName);
                 assertEquals(ROUTE_ID1, routeId);
@@ -557,8 +557,8 @@
         }
     }
 
-    void setProxy(SampleMediaRoute2ProviderService.Proxy proxy) {
-        SampleMediaRoute2ProviderService service = mService;
+    void setProxy(StubMediaRoute2ProviderService.Proxy proxy) {
+        StubMediaRoute2ProviderService service = mService;
         if (service != null) {
             service.setProxy(proxy);
         }
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
index b97e156..0c87a2a 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
@@ -18,14 +18,14 @@
 
 import static android.content.Context.AUDIO_SERVICE;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURES_SPECIAL;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID1;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID2;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID3_SESSION_CREATION_FAILED;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURES_SPECIAL;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID1;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID2;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID3_SESSION_CREATION_FAILED;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -72,7 +72,7 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "The system should be able to bind to SampleMediaRoute2ProviderService")
+@AppModeFull(reason = "The system should be able to bind to StubMediaRoute2ProviderService")
 @LargeTest
 public class MediaRouter2Test {
     private static final String TAG = "MR2Test";
@@ -80,7 +80,7 @@
     private MediaRouter2 mRouter2;
     private Executor mExecutor;
     private AudioManager mAudioManager;
-    private SampleMediaRoute2ProviderService mService;
+    private StubMediaRoute2ProviderService mService;
 
     private static final int TIMEOUT_MS = 5000;
     private static final int WAIT_MS = 2000;
@@ -100,8 +100,8 @@
         new PollingCheck(TIMEOUT_MS) {
             @Override
             protected boolean check() {
-                SampleMediaRoute2ProviderService service =
-                        SampleMediaRoute2ProviderService.getInstance();
+                StubMediaRoute2ProviderService service =
+                        StubMediaRoute2ProviderService.getInstance();
                 if (service != null) {
                     mService = service;
                     return true;
@@ -362,7 +362,7 @@
                     assertTrue(createRouteMap(newController.getSelectedRoutes()).containsKey(
                             ROUTE_ID1));
 
-                    // The SampleMediaRoute2ProviderService is supposed to set control hints
+                    // The StubMediaRoute2ProviderService is supposed to set control hints
                     // with the given controllerHints.
                     Bundle controlHints = newController.getControlHints();
                     assertNotNull(controlHints);
@@ -387,7 +387,7 @@
         try {
             mRouter2.registerTransferCallback(mExecutor, transferCallback);
 
-            // The SampleMediaRoute2ProviderService supposed to set control hints
+            // The StubMediaRoute2ProviderService supposed to set control hints
             // with the given creationSessionHints.
             mRouter2.setOnGetControllerHintsListener(listener);
             mRouter2.transferTo(route);
diff --git a/tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
similarity index 88%
rename from tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java
rename to tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
index 4b51731..326adb0 100644
--- a/tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
@@ -31,7 +31,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.text.TextUtils;
-import android.util.Log;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -41,7 +40,7 @@
 
 import javax.annotation.concurrent.GuardedBy;
 
-public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
+public class StubMediaRoute2ProviderService extends MediaRoute2ProviderService {
     private static final String TAG = "SampleMR2ProviderSvc";
     private static final Object sLock = new Object();
 
@@ -89,7 +88,7 @@
     private int mNextSessionId = 1000;
 
     @GuardedBy("sLock")
-    private static SampleMediaRoute2ProviderService sInstance;
+    private static StubMediaRoute2ProviderService sInstance;
     private Proxy mProxy;
 
     public void initializeRoutes() {
@@ -140,7 +139,7 @@
         mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute);
     }
 
-    public static SampleMediaRoute2ProviderService getInstance() {
+    public static StubMediaRoute2ProviderService getInstance() {
         synchronized (sLock) {
             return sInstance;
         }
@@ -183,7 +182,7 @@
     }
 
     @Override
-    public void onSetRouteVolume(String routeId, int volume) {
+    public void onSetRouteVolume(long requestId, String routeId, int volume) {
         MediaRoute2Info route = mRoutes.get(routeId);
         if (route == null) {
             return;
@@ -196,7 +195,7 @@
     }
 
     @Override
-    public void onSetSessionVolume(String sessionId, int volume) {
+    public void onSetSessionVolume(long requestId, String sessionId, int volume) {
         RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
         if (sessionInfo == null) {
             return;
@@ -209,11 +208,11 @@
     }
 
     @Override
-    public void onCreateSession(String packageName, String routeId, long requestId,
+    public void onCreateSession(long requestId, String packageName, String routeId,
             @Nullable Bundle sessionHints) {
         Proxy proxy = mProxy;
         if (doesProxyOverridesMethod(proxy, "onCreateSession")) {
-            proxy.onCreateSession(packageName, routeId, requestId, sessionHints);
+            proxy.onCreateSession(requestId, packageName, routeId, sessionHints);
             return;
         }
 
@@ -223,7 +222,7 @@
             notifySessionCreationFailed(requestId);
             return;
         }
-        maybeDeselectRoute(routeId);
+        maybeDeselectRoute(routeId, requestId);
 
         final String sessionId = String.valueOf(mNextSessionId);
         mNextSessionId++;
@@ -248,10 +247,10 @@
     }
 
     @Override
-    public void onReleaseSession(String sessionId) {
+    public void onReleaseSession(long requestId, String sessionId) {
         Proxy proxy = mProxy;
         if (doesProxyOverridesMethod(proxy, "onReleaseSession")) {
-            proxy.onReleaseSession(sessionId);
+            proxy.onReleaseSession(requestId, sessionId);
             return;
         }
 
@@ -286,10 +285,10 @@
     }
 
     @Override
-    public void onSelectRoute(String sessionId, String routeId) {
+    public void onSelectRoute(long requestId, String sessionId, String routeId) {
         Proxy proxy = mProxy;
         if (doesProxyOverridesMethod(proxy, "onSelectRoute")) {
-            proxy.onSelectRoute(sessionId, routeId);
+            proxy.onSelectRoute(requestId, sessionId, routeId);
             return;
         }
 
@@ -298,7 +297,7 @@
         if (route == null || sessionInfo == null) {
             return;
         }
-        maybeDeselectRoute(routeId);
+        maybeDeselectRoute(routeId, requestId);
 
         mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
                 .setClientPackageName(sessionInfo.getClientPackageName())
@@ -315,10 +314,10 @@
     }
 
     @Override
-    public void onDeselectRoute(String sessionId, String routeId) {
+    public void onDeselectRoute(long requestId, String sessionId, String routeId) {
         Proxy proxy = mProxy;
         if (doesProxyOverridesMethod(proxy, "onDeselectRoute")) {
-            proxy.onDeselectRoute(sessionId, routeId);
+            proxy.onDeselectRoute(requestId, sessionId, routeId);
             return;
         }
 
@@ -350,10 +349,10 @@
     }
 
     @Override
-    public void onTransferToRoute(String sessionId, String routeId) {
+    public void onTransferToRoute(long requestId, String sessionId, String routeId) {
         Proxy proxy = mProxy;
         if (doesProxyOverridesMethod(proxy, "onTransferToRoute")) {
-            proxy.onTransferToRoute(sessionId, routeId);
+            proxy.onTransferToRoute(requestId, sessionId, routeId);
             return;
         }
 
@@ -389,13 +388,13 @@
         publishRoutes();
     }
 
-    void maybeDeselectRoute(String routeId) {
+    void maybeDeselectRoute(String routeId, long requestId) {
         if (!mRouteIdToSessionId.containsKey(routeId)) {
             return;
         }
 
         String sessionId = mRouteIdToSessionId.get(routeId);
-        onDeselectRoute(sessionId, routeId);
+        onDeselectRoute(requestId, sessionId, routeId);
     }
 
     void publishRoutes() {
@@ -403,12 +402,15 @@
     }
 
     public static class Proxy {
-        public void onCreateSession(@NonNull String packageName, @NonNull String routeId,
-                long requestId, @Nullable Bundle sessionHints) {}
-        public void onReleaseSession(@NonNull String sessionId) {}
-        public void onSelectRoute(@NonNull String sessionId, @NonNull String routeId) {}
-        public void onDeselectRoute(@NonNull String sessionId, @NonNull String routeId) {}
-        public void onTransferToRoute(@NonNull String sessionId, @NonNull String routeId) {}
+        public void onCreateSession(long requestId, @NonNull String packageName,
+                @NonNull String routeId, @Nullable Bundle sessionHints) {}
+        public void onReleaseSession(long requestId, @NonNull String sessionId) {}
+        public void onSelectRoute(long requestId, @NonNull String sessionId,
+                @NonNull String routeId) {}
+        public void onDeselectRoute(long requestId, @NonNull String sessionId,
+                @NonNull String routeId) {}
+        public void onTransferToRoute(long requestId, @NonNull String sessionId,
+                @NonNull String routeId) {}
         public void onDiscoveryPreferenceChanged(RouteDiscoveryPreference preference) {}
         // TODO: Handle onSetRouteVolume() && onSetSessionVolume()
     }
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
index 813b40c..4a89d69 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
@@ -55,17 +55,48 @@
     return latencyMillis;
 }
 
-using CbTestParams = std::tuple<aaudio_sharing_mode_t, int32_t, aaudio_performance_mode_t>;
+using CbTestParams = std::tuple<aaudio_sharing_mode_t, int32_t,
+                                aaudio_performance_mode_t, int32_t, aaudio_format_t>;
 enum {
     PARAM_SHARING_MODE = 0,
     PARAM_FRAMES_PER_CB,
-    PARAM_PERF_MODE
+    PARAM_PERF_MODE,
+    PARAM_ALLOW_MMAP,
+    PARAM_AUDIO_FORMAT
 };
 
+enum {
+    MMAP_NOT_ALLOWED,
+    MMAP_ALLOWED,
+};
+
+static const char* allowMMapToString(int allow) {
+    switch (allow) {
+        case MMAP_NOT_ALLOWED: return "NOTMMAP";
+        case MMAP_ALLOWED:
+        default:
+            return "MMAPOK";
+    }
+}
+
+static const char* audioFormatToString(aaudio_format_t format) {
+    switch (format) {
+        case AAUDIO_FORMAT_UNSPECIFIED: return "UNSP";
+        case AAUDIO_FORMAT_PCM_I16: return "I16";
+        case AAUDIO_FORMAT_PCM_FLOAT: return "FLT";
+        default:
+            return "BAD";
+    }
+}
+
 static std::string getTestName(const ::testing::TestParamInfo<CbTestParams>& info) {
-    return std::string() + sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param)) +
-            "__" + std::to_string(std::get<PARAM_FRAMES_PER_CB>(info.param)) +
-            "__" + performanceModeToString(std::get<PARAM_PERF_MODE>(info.param));
+    return std::string()
+            + sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param))
+            + "__" + std::to_string(std::get<PARAM_FRAMES_PER_CB>(info.param))
+            + "__" + performanceModeToString(std::get<PARAM_PERF_MODE>(info.param))
+            + "__" + allowMMapToString(std::get<PARAM_ALLOW_MMAP>(info.param))
+            + "__" + audioFormatToString(std::get<PARAM_AUDIO_FORMAT>(info.param))
+            ;
 }
 
 template<typename T>
@@ -143,11 +174,15 @@
 }
 
 void AAudioInputStreamCallbackTest::SetUp() {
+    aaudio_policy_t originalPolicy = AAUDIO_POLICY_AUTO;
+
     mSetupSuccesful = false;
     if (!deviceSupportsFeature(FEATURE_RECORDING)) return;
     mHelper.reset(new InputStreamBuilderHelper(
                     std::get<PARAM_SHARING_MODE>(GetParam()),
-                    std::get<PARAM_PERF_MODE>(GetParam())));
+                    std::get<PARAM_PERF_MODE>(GetParam()),
+                    std::get<PARAM_AUDIO_FORMAT>(GetParam()))
+                    );
     mHelper->initBuilder();
 
     int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
@@ -158,7 +193,23 @@
         AAudioStreamBuilder_setFramesPerDataCallback(builder(), framesPerDataCallback);
     }
 
+    // Turn off MMap if requested.
+    int allowMMap = std::get<PARAM_ALLOW_MMAP>(GetParam()) == MMAP_ALLOWED;
+    if (AAudioExtensions::getInstance().isMMapSupported()) {
+        originalPolicy = AAudioExtensions::getInstance().getMMapPolicy();
+        AAudioExtensions::getInstance().setMMapEnabled(allowMMap);
+    }
+
     mHelper->createAndVerifyStream(&mSetupSuccesful);
+
+    // Restore policy for next test.
+    if (AAudioExtensions::getInstance().isMMapSupported()) {
+        AAudioExtensions::getInstance().setMMapPolicy(originalPolicy);
+    }
+    if (!allowMMap) {
+        ASSERT_FALSE(AAudioExtensions::getInstance().isMMapUsed(mHelper->stream()));
+    }
+
 }
 
 // Test Reading from an AAudioStream using a Callback
@@ -166,12 +217,12 @@
     if (!mSetupSuccesful) return;
 
     const int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
-    const int32_t actualFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
+    const int32_t streamFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
     if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
-        ASSERT_EQ(framesPerDataCallback, actualFramesPerDataCallback);
+        ASSERT_EQ(framesPerDataCallback, streamFramesPerDataCallback);
     }
 
-    mCbData->reset(actualFramesPerDataCallback);
+    mCbData->reset(streamFramesPerDataCallback);
 
     mHelper->startStream();
     // See b/62090113. For legacy path, the device is only known after
@@ -189,8 +240,8 @@
     sleep(1);
     EXPECT_EQ(oldCallbackCount, mCbData->callbackCount); // expect not advancing
 
-    if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
-        ASSERT_EQ(framesPerDataCallback, mCbData->actualFramesPerCallback);
+    if (streamFramesPerDataCallback != AAUDIO_UNSPECIFIED) {
+        ASSERT_EQ(streamFramesPerDataCallback, mCbData->actualFramesPerCallback);
     }
 
     ASSERT_EQ(AAUDIO_OK, mCbData->callbackError);
@@ -201,16 +252,42 @@
                 std::make_tuple(
                         AAUDIO_SHARING_MODE_SHARED,
                         AAUDIO_UNSPECIFIED,
-                        AAUDIO_PERFORMANCE_MODE_NONE),
-                // cb buffer size: arbitrary prime number < 192
-                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 109, AAUDIO_PERFORMANCE_MODE_NONE),
+                        AAUDIO_PERFORMANCE_MODE_NONE,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                // cb buffer size: arbitrary prime number < 96
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+                        AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_EXCLUSIVE, 67,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+                        AAUDIO_FORMAT_PCM_I16),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+                        AAUDIO_FORMAT_PCM_FLOAT),
                 // cb buffer size: arbitrary prime number > 192
-                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223,
+                        AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
                 // Recording in POWER_SAVING mode isn't supported, b/62291775.
                 std::make_tuple(
                         AAUDIO_SHARING_MODE_SHARED,
                         AAUDIO_UNSPECIFIED,
-                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY)),
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(
+                        AAUDIO_SHARING_MODE_EXCLUSIVE,
+                        AAUDIO_UNSPECIFIED,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED)),
         &getTestName);
 
 
@@ -224,7 +301,10 @@
 
 // Callback function that fills the audio output buffer.
 aaudio_data_callback_result_t AAudioOutputStreamCallbackTest::MyDataCallbackProc(
-        AAudioStream *stream, void *userData, void *audioData, int32_t numFrames) {
+        AAudioStream *stream,
+        void *userData,
+        void *audioData,
+        int32_t numFrames) {
     int32_t channelCount = AAudioStream_getChannelCount(stream);
     int32_t numSamples = channelCount * numFrames;
     if (AAudioStream_getFormat(stream) == AAUDIO_FORMAT_PCM_I16) {
@@ -247,7 +327,9 @@
     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
     mHelper.reset(new OutputStreamBuilderHelper(
                     std::get<PARAM_SHARING_MODE>(GetParam()),
-                    std::get<PARAM_PERF_MODE>(GetParam())));
+                    std::get<PARAM_PERF_MODE>(GetParam()),
+                    std::get<PARAM_AUDIO_FORMAT>(GetParam()))
+                    );
     mHelper->initBuilder();
 
     int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
@@ -259,6 +341,7 @@
     }
 
     mHelper->createAndVerifyStream(&mSetupSuccesful);
+
 }
 
 // Test Writing to an AAudioStream using a Callback
@@ -266,15 +349,15 @@
     if (!mSetupSuccesful) return;
 
     const int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
-    const int32_t actualFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
+    const int32_t streamFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
     if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
-        ASSERT_EQ(framesPerDataCallback, actualFramesPerDataCallback);
+        ASSERT_EQ(framesPerDataCallback, streamFramesPerDataCallback);
     }
 
     // Start/stop more than once to see if it fails after the first time.
     // Write some data and measure the rate to see if the timing is OK.
     for (int loopIndex = 0; loopIndex < 2; loopIndex++) {
-        mCbData->reset(actualFramesPerDataCallback);
+        mCbData->reset(streamFramesPerDataCallback);
 
         mHelper->startStream();
         // See b/62090113. For legacy path, the device is only known after
@@ -297,8 +380,8 @@
         sleep(1);
         EXPECT_EQ(oldCallbackCount, mCbData->callbackCount); // expect not advancing
 
-        if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
-            ASSERT_EQ(framesPerDataCallback, mCbData->actualFramesPerCallback);
+        if (streamFramesPerDataCallback != AAUDIO_UNSPECIFIED) {
+            ASSERT_EQ(streamFramesPerDataCallback, mCbData->actualFramesPerCallback);
         }
 
         EXPECT_GE(mCbData->minLatency, 1);   // Absurdly low
@@ -318,17 +401,39 @@
                 std::make_tuple(
                         AAUDIO_SHARING_MODE_SHARED,
                         AAUDIO_UNSPECIFIED,
-                        AAUDIO_PERFORMANCE_MODE_NONE),
-                // cb buffer size: arbitrary prime number < 192
-                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 109, AAUDIO_PERFORMANCE_MODE_NONE),
+                        AAUDIO_PERFORMANCE_MODE_NONE,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                // cb buffer size: arbitrary prime number < 96
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_EXCLUSIVE, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+                        AAUDIO_FORMAT_PCM_I16),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+                        AAUDIO_FORMAT_PCM_FLOAT),
                 // cb buffer size: arbitrary prime number > 192
-                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE),
+                std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
                 std::make_tuple(
                         AAUDIO_SHARING_MODE_SHARED,
                         AAUDIO_UNSPECIFIED,
-                        AAUDIO_PERFORMANCE_MODE_POWER_SAVING),
+                        AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
                 std::make_tuple(
                         AAUDIO_SHARING_MODE_SHARED,
                         AAUDIO_UNSPECIFIED,
-                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY)),
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED),
+                std::make_tuple(
+                        AAUDIO_SHARING_MODE_EXCLUSIVE,
+                        AAUDIO_UNSPECIFIED,
+                        AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+                        MMAP_ALLOWED,
+                        AAUDIO_FORMAT_UNSPECIFIED)),
         &getTestName);
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
index fd67644..f08e1df 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
@@ -28,43 +28,9 @@
 #include "test_aaudio.h"
 #include "utils.h"
 
-/* These definitions are from aaudio/AAudioTesting.h */
-enum {
-    AAUDIO_POLICY_NEVER = 1,
-    AAUDIO_POLICY_AUTO,
-    AAUDIO_POLICY_ALWAYS
-};
-typedef int32_t aaudio_policy_t;
-
-static aaudio_result_t (*s_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
-static aaudio_policy_t (*s_getMMapPolicy)() = nullptr;
-
-/**
- * @return integer value or -1 on error
- */
-static int getSystemPropertyInt(const char *propName, int defaultValue) {
-    char valueText[PROP_VALUE_MAX] = {'\0'};
-    if (__system_property_get(propName, valueText) <= 0) {
-        return defaultValue;
-    }
-    char *endptr = nullptr;
-    int value = strtol(valueText, &endptr, 10);
-    if (endptr == nullptr || *endptr != '\0') {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-                "getSystemPropertyInt() - non-integer value = %s", valueText);
-        return -1;
-    } else {
-        return value;
-    }
-}
-
-static int getSystemMMapPolicy() {
-    return getSystemPropertyInt("aaudio.mmap_policy", AAUDIO_UNSPECIFIED);
-}
-
 // Test allowed values of policy.
 TEST(test_aaudio_mmap, testCurrentPolicy) {
-    aaudio_policy_t policy = getSystemMMapPolicy();
+    aaudio_policy_t policy = (aaudio_policy_t) AAudioExtensions::getMMapPolicyProperty();
 
     // It must be one of these defined enum values.
     EXPECT_TRUE(policy == AAUDIO_UNSPECIFIED
@@ -78,19 +44,6 @@
     EXPECT_NE(AAUDIO_POLICY_ALWAYS, policy);
 }
 
-// Link to test functions in shared library.
-static void loadMMapTestFunctions() {
-    if (s_setMMapPolicy != nullptr) return; // already loaded
-
-    void *handle;
-    handle = dlopen("libaaudio.so", RTLD_NOW);
-    EXPECT_NE(nullptr, handle);
-    s_setMMapPolicy = (int (*)(int)) dlsym(handle, "AAudio_setMMapPolicy");
-    EXPECT_NE(nullptr, s_setMMapPolicy);
-    s_getMMapPolicy = (int (*)()) dlsym(handle, "AAudio_getMMapPolicy");
-    EXPECT_NE(nullptr, s_getMMapPolicy);
-}
-
 // An application should not be able to create an MMAP stream
 // by enabling MMAP when the system "aaudio.mmap_policy" says not to.
 TEST(test_aaudio_mmap, testElevatingMMapPolicy) {
@@ -98,12 +51,8 @@
     AAudioStreamBuilder *builder = nullptr;
     AAudioStream *stream = nullptr;
 
-    aaudio_policy_t policy = getSystemMMapPolicy();
-    bool mmapAllowed = (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
+    bool mmapAllowed = AAudioExtensions::getInstance().isMMapSupported();
     if (mmapAllowed) return;
-    // Try to enable MMAP when not allowed.
-
-    loadMMapTestFunctions();
 
     EXPECT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&builder));
 
@@ -111,10 +60,10 @@
     AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
 
     // Force policy to create an MMAP stream or fail.
-    aaudio_policy_t originalPolicy = s_getMMapPolicy();
-    s_setMMapPolicy(AAUDIO_POLICY_ALWAYS); // try to enable MMAP mode
+    aaudio_policy_t originalPolicy = AAudioExtensions::getInstance().getMMapPolicy();
+    AAudioExtensions::getInstance().setMMapPolicy(AAUDIO_POLICY_ALWAYS); // try to enable MMAP mode
     result = AAudioStreamBuilder_openStream(builder, &stream);
-    s_setMMapPolicy(originalPolicy);
+    AAudioExtensions::getInstance().setMMapPolicy(originalPolicy);
 
     // openStream should have failed.
     EXPECT_NE(AAUDIO_OK, result);
diff --git a/tests/tests/nativemedia/aaudio/jni/utils.cpp b/tests/tests/nativemedia/aaudio/jni/utils.cpp
index d843614..a9ed984 100644
--- a/tests/tests/nativemedia/aaudio/jni/utils.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/utils.cpp
@@ -149,7 +149,9 @@
     ASSERT_LE(mActual.channelCount, 16); // TODO what is min/max?
 
     mActual.dataFormat = AAudioStream_getFormat(mStream);
-    ASSERT_EQ(AAUDIO_FORMAT_PCM_I16, mActual.dataFormat);
+    if (mRequested.dataFormat != AAUDIO_FORMAT_UNSPECIFIED) {
+        ASSERT_EQ(mRequested.dataFormat, mActual.dataFormat);
+    }
 
     mActual.perfMode = AAudioStream_getPerformanceMode(mStream);
     if (mRequested.perfMode != AAUDIO_PERFORMANCE_MODE_NONE
@@ -192,17 +194,20 @@
     ASSERT_EQ(toState, state);
 }
 
-
 InputStreamBuilderHelper::InputStreamBuilderHelper(
-        aaudio_sharing_mode_t requestedSharingMode, aaudio_performance_mode_t requestedPerfMode)
+        aaudio_sharing_mode_t requestedSharingMode,
+        aaudio_performance_mode_t requestedPerfMode,
+        aaudio_format_t requestedFormat)
         : StreamBuilderHelper{AAUDIO_DIRECTION_INPUT,
-            48000, 1, AAUDIO_FORMAT_PCM_I16, requestedSharingMode, requestedPerfMode} {}
+            48000, 1, requestedFormat, requestedSharingMode, requestedPerfMode} {}
 
 
 OutputStreamBuilderHelper::OutputStreamBuilderHelper(
-        aaudio_sharing_mode_t requestedSharingMode, aaudio_performance_mode_t requestedPerfMode)
+        aaudio_sharing_mode_t requestedSharingMode,
+        aaudio_performance_mode_t requestedPerfMode,
+        aaudio_format_t requestedFormat)
         : StreamBuilderHelper{AAUDIO_DIRECTION_OUTPUT,
-            48000, 2, AAUDIO_FORMAT_PCM_I16, requestedSharingMode, requestedPerfMode} {}
+            48000, 2, requestedFormat, requestedSharingMode, requestedPerfMode} {}
 
 void OutputStreamBuilderHelper::initBuilder() {
     StreamBuilderHelper::initBuilder();
@@ -215,3 +220,51 @@
         ASSERT_GE(AAudioStream_getBufferCapacityInFrames(mStream), kBufferCapacityFrames);
     }
 }
+
+AAudioExtensions::AAudioExtensions()
+    : mMMapSupported(isPolicyEnabled(getMMapPolicyProperty()))
+    , mMMapExclusiveSupported(isPolicyEnabled(getIntegerProperty(
+            "aaudio.mmap_exclusive_policy", AAUDIO_POLICY_UNSPECIFIED))) {
+    loadLibrary();
+}
+
+int AAudioExtensions::getIntegerProperty(const char *name, int defaultValue) {
+    int result = defaultValue;
+    char valueText[PROP_VALUE_MAX] = {0};
+    if (__system_property_get(name, valueText) != 0) {
+        result = atoi(valueText);
+    }
+    return result;
+}
+
+// This should only be called once from the constructor.
+bool AAudioExtensions::loadLibrary() {
+    mLibHandle = dlopen(LIB_AAUDIO_NAME, 0);
+    if (mLibHandle == nullptr) {
+        //LOGI("%s() could not find " LIB_AAUDIO_NAME, __func__);
+        return false;
+    }
+
+    mAAudioStream_isMMap = (bool (*)(AAudioStream *stream))
+            dlsym(mLibHandle, FUNCTION_IS_MMAP);
+    if (mAAudioStream_isMMap == nullptr) {
+        //LOGI("%s() could not find " FUNCTION_IS_MMAP, __func__);
+        return false;
+    }
+
+    mAAudio_setMMapPolicy = (int32_t (*)(aaudio_policy_t policy))
+            dlsym(mLibHandle, FUNCTION_SET_MMAP_POLICY);
+    if (mAAudio_setMMapPolicy == nullptr) {
+        //LOGI("%s() could not find " FUNCTION_SET_MMAP_POLICY, __func__);
+        return false;
+    }
+
+    mAAudio_getMMapPolicy = (aaudio_policy_t (*)())
+            dlsym(mLibHandle, FUNCTION_GET_MMAP_POLICY);
+    if (mAAudio_getMMapPolicy == nullptr) {
+        //LOGI("%s() could not find " FUNCTION_GET_MMAP_POLICY, __func__);
+        return false;
+    }
+    mFunctionsLoaded = true;
+    return mFunctionsLoaded;
+}
\ No newline at end of file
diff --git a/tests/tests/nativemedia/aaudio/jni/utils.h b/tests/tests/nativemedia/aaudio/jni/utils.h
index 4211410..f14e04d 100644
--- a/tests/tests/nativemedia/aaudio/jni/utils.h
+++ b/tests/tests/nativemedia/aaudio/jni/utils.h
@@ -16,7 +16,9 @@
 #ifndef CTS_MEDIA_TEST_AAUDIO_UTILS_H
 #define CTS_MEDIA_TEST_AAUDIO_UTILS_H
 
+#include <dlfcn.h>
 #include <map>
+#include <sys/system_properties.h>
 
 #include <aaudio/AAudio.h>
 
@@ -88,14 +90,16 @@
   public:
     InputStreamBuilderHelper(
             aaudio_sharing_mode_t requestedSharingMode,
-            aaudio_performance_mode_t requestedPerfMode);
+            aaudio_performance_mode_t requestedPerfMode,
+            aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_FLOAT);
 };
 
 class OutputStreamBuilderHelper : public StreamBuilderHelper {
   public:
     OutputStreamBuilderHelper(
             aaudio_sharing_mode_t requestedSharingMode,
-            aaudio_performance_mode_t requestedPerfMode);
+            aaudio_performance_mode_t requestedPerfMode,
+            aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_I16);
     void initBuilder();
     void createAndVerifyStream(bool *success);
 
@@ -103,4 +107,91 @@
     const int32_t kBufferCapacityFrames = 2000;
 };
 
+
+#define LIB_AAUDIO_NAME          "libaaudio.so"
+#define FUNCTION_IS_MMAP         "AAudioStream_isMMapUsed"
+#define FUNCTION_SET_MMAP_POLICY "AAudio_setMMapPolicy"
+#define FUNCTION_GET_MMAP_POLICY "AAudio_getMMapPolicy"
+
+enum {
+    AAUDIO_POLICY_UNSPECIFIED = 0,
+/* These definitions are from aaudio/AAudioTesting.h */
+    AAUDIO_POLICY_NEVER = 1,
+    AAUDIO_POLICY_AUTO = 2,
+    AAUDIO_POLICY_ALWAYS = 3
+};
+typedef int32_t aaudio_policy_t;
+
+/**
+ * Call some AAudio test routines that are not part of the normal API.
+ */
+class AAudioExtensions {
+public:
+    AAudioExtensions();
+
+    static bool isPolicyEnabled(int32_t policy) {
+        return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
+    }
+
+    static AAudioExtensions &getInstance() {
+        static AAudioExtensions instance;
+        return instance;
+    }
+
+    static int getMMapPolicyProperty() {
+        return getIntegerProperty("aaudio.mmap_policy", AAUDIO_POLICY_UNSPECIFIED);
+    }
+
+    aaudio_policy_t getMMapPolicy() {
+        if (!mFunctionsLoaded) return -1;
+        return mAAudio_getMMapPolicy();
+    }
+
+    int32_t setMMapPolicy(aaudio_policy_t policy) {
+        if (!mFunctionsLoaded) return -1;
+        return mAAudio_setMMapPolicy(policy);
+    }
+
+    bool isMMapUsed(AAudioStream *aaudioStream) {
+        if (!mFunctionsLoaded) return false;
+        return mAAudioStream_isMMap(aaudioStream);
+    }
+
+    int32_t setMMapEnabled(bool enabled) {
+        return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER);
+    }
+
+    bool isMMapEnabled() {
+        return isPolicyEnabled(mAAudio_getMMapPolicy());
+    }
+
+    bool isMMapSupported() const {
+        return mMMapSupported;
+    }
+
+    bool isMMapExclusiveSupported() const {
+        return mMMapExclusiveSupported;
+    }
+
+private:
+
+    static int getIntegerProperty(const char *name, int defaultValue);
+
+    /**
+     * Load some AAudio test functions.
+     * This should only be called once from the constructor.
+     * @return true if it succeeds
+     */
+    bool loadLibrary();
+
+    bool      mFunctionsLoaded = false;
+    void     *mLibHandle = nullptr;
+    bool    (*mAAudioStream_isMMap)(AAudioStream *stream) = nullptr;
+    int32_t (*mAAudio_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
+    aaudio_policy_t (*mAAudio_getMMapPolicy)() = nullptr;
+
+    const bool   mMMapSupported;
+    const bool   mMMapExclusiveSupported;
+};
+
 #endif  // CTS_MEDIA_TEST_AAUDIO_UTILS_H
diff --git a/tests/tests/ndef/OWNERS b/tests/tests/ndef/OWNERS
index 8ffbd10..d92b2ab 100644
--- a/tests/tests/ndef/OWNERS
+++ b/tests/tests/ndef/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 48448
-rmojumder@google.com
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
 zachoverflow@google.com
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
index c32a7a0..1cc49f9 100644
--- a/tests/tests/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -86,7 +86,7 @@
     static final int CANCEL_RETRY_TIMES = 5;
     static final int QUERY_TIMES = 10;
     static final int NXDOMAIN = 3;
-    static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 2_000;
+    static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000;
 
     private ContentResolver mCR;
     private ConnectivityManager mCM;
@@ -122,10 +122,15 @@
         mOldDnsSpecifier = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER);
     }
 
-    private void restorePrivateDnsSetting() {
+    private void restorePrivateDnsSetting() throws InterruptedException {
         // restore private DNS setting
         Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldMode);
-        Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier);
+        if ("hostname".equals(mOldMode)) {
+            Settings.Global.putString(
+                mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier);
+            mCtsNetUtils.awaitPrivateDnsSetting("restorePrivateDnsSetting timeout",
+                    mCM.getActiveNetwork(), mOldDnsSpecifier, PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
+        }
     }
 
     private static String byteArrayToHexString(byte[] bytes) {
@@ -203,6 +208,7 @@
         private final CancellationSignal mCancelSignal;
         private int mRcode;
         private DnsAnswer mDnsAnswer;
+        private String mErrorMsg = null;
 
         VerifyCancelCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
             mMsg = msg;
@@ -228,14 +234,18 @@
         @Override
         public void onAnswer(@NonNull byte[] answer, int rcode) {
             if (mCancelSignal != null && mCancelSignal.isCanceled()) {
-                fail(mMsg + " should not have returned any answers");
+                mErrorMsg = mMsg + " should not have returned any answers";
+                mLatch.countDown();
+                return;
             }
 
             mRcode = rcode;
             try {
                 mDnsAnswer = new DnsAnswer(answer);
             } catch (ParseException | DnsParseException e) {
-                fail(mMsg + e.getMessage());
+                mErrorMsg = mMsg + e.getMessage();
+                mLatch.countDown();
+                return;
             }
             Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
             mLatch.countDown();
@@ -243,10 +253,12 @@
 
         @Override
         public void onError(@NonNull DnsResolver.DnsException error) {
-            fail(mMsg + error.getMessage());
+            mErrorMsg = mMsg + error.getMessage();
+            mLatch.countDown();
         }
 
         private void assertValidAnswer() {
+            assertNull(mErrorMsg);
             assertNotNull(mMsg + " No valid answer", mDnsAnswer);
             assertEquals(mMsg + " Unexpected error: reported rcode" + mRcode +
                     " blob's rcode " + mDnsAnswer.getRcode(), mRcode, mDnsAnswer.getRcode());
@@ -402,20 +414,18 @@
     public void doTestRawQueryNXDomainWithPrivateDns(Executor executor)
             throws InterruptedException {
         final String msg = "RawQuery " + TEST_NX_DOMAIN + " with private DNS";
-
         // Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
         // b/144521720
         Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname");
         Settings.Global.putString(mCR,
                 Settings.Global.PRIVATE_DNS_SPECIFIER, GOOGLE_PRIVATE_DNS_SERVER);
-
         for (Network network :  getTestableNetworks()) {
             final Network networkForPrivateDns =
                     (network != null) ? network : mCM.getActiveNetwork();
             assertNotNull("Can't find network to await private DNS on", networkForPrivateDns);
             mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
                     networkForPrivateDns, GOOGLE_PRIVATE_DNS_SERVER,
-                    PRIVATE_DNS_SETTING_TIMEOUT_MS);
+                    PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
             final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
             mDns.rawQuery(network, TEST_NX_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
                     executor, null, callback);
@@ -508,6 +518,7 @@
         private final String mMsg;
         private final List<InetAddress> mAnswers;
         private final CancellationSignal mCancelSignal;
+        private String mErrorMsg = null;
 
         VerifyCancelInetAddressCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
             this.mMsg = msg;
@@ -541,10 +552,16 @@
             return false;
         }
 
+        public void assertNoError() {
+            assertNull(mErrorMsg);
+        }
+
         @Override
         public void onAnswer(@NonNull List<InetAddress> answerList, int rcode) {
             if (mCancelSignal != null && mCancelSignal.isCanceled()) {
-                fail(mMsg + " should not have returned any answers");
+                mErrorMsg = mMsg + " should not have returned any answers";
+                mLatch.countDown();
+                return;
             }
             for (InetAddress addr : answerList) {
                 Log.d(TAG, "Reported addr: " + addr.toString());
@@ -556,7 +573,7 @@
 
         @Override
         public void onError(@NonNull DnsResolver.DnsException error) {
-            fail(mMsg + error.getMessage());
+            mErrorMsg = mMsg + error.getMessage();
         }
     }
 
@@ -601,6 +618,7 @@
 
             assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
                     callback.waitForAnswer());
+            callback.assertNoError();
             assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
         }
     }
@@ -644,6 +662,7 @@
 
             assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
                     callback.waitForAnswer());
+            callback.assertNoError();
             assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
             assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer());
         }
@@ -659,6 +678,7 @@
 
             assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
                     callback.waitForAnswer());
+            callback.assertNoError();
             assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
             assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer());
         }
@@ -671,7 +691,6 @@
         Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname");
         Settings.Global.putString(mCR,
                 Settings.Global.PRIVATE_DNS_SPECIFIER, INVALID_PRIVATE_DNS_SERVER);
-
         final String msg = "Test PrivateDnsBypass " + TEST_DOMAIN;
         for (Network network : testNetworks) {
             // This test cannot be ran with null network because we need to explicitly pass a
@@ -680,7 +699,7 @@
 
             // wait for private DNS setting propagating
             mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
-                    network, INVALID_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS);
+                    network, INVALID_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, false);
 
             final CountDownLatch latch = new CountDownLatch(1);
             final DnsResolver.Callback<List<InetAddress>> errorCallback =
@@ -712,6 +731,7 @@
 
             assertTrue(msg + " bypass private DNS round. No answer after " + TIMEOUT_MS + "ms.",
                     callback.waitForAnswer());
+            callback.assertNoError();
             assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
 
             // To ensure private DNS bypass still work even if passing null network.
@@ -724,6 +744,7 @@
 
             assertTrue(msg + " with null network bypass private DNS round. No answer after " +
                     TIMEOUT_MS + "ms.", callbackWithNullNetwork.waitForAnswer());
+            callbackWithNullNetwork.assertNoError();
             assertTrue(msg + " with null network returned 0 results",
                     !callbackWithNullNetwork.isAnswerEmpty());
 
@@ -745,6 +766,7 @@
 
                 assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
                         callback.waitForAnswer());
+                callback.assertNoError();
                 assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
                 assertTrue(msg + " returned " + (queryV6 ? "Ipv4" : "Ipv6") + " results",
                         queryV6 ? !callback.hasIpv4Answer() : !callback.hasIpv6Answer());
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
index 766c55e..f123187 100644
--- a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -245,7 +245,7 @@
             for (Network network : getTestableNetworks()) {
               // Wait for private DNS setting to propagate.
               mCtsNetUtils.awaitPrivateDnsSetting("NxDomain test wait private DNS setting timeout",
-                        network, GOOGLE_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS);
+                        network, GOOGLE_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
               runResNnxDomainCheck(network.getNetworkHandle());
             }
         } finally {
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 d943231..6f94fea 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -16,11 +16,13 @@
 
 package android.net.wifi.cts;
 
+import static com.google.common.truth.Truth.assertThat;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
@@ -78,13 +80,13 @@
 
         mContext.registerReceiver(mReceiver, mIntentFilter);
         mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertNotNull(mWifiManager);
+        assertThat(mWifiManager).isNotNull();
         mWifiLock = mWifiManager.createWifiLock(TAG);
         mWifiLock.acquire();
         if (!mWifiManager.isWifiEnabled())
             setWifiEnabled(true);
         Thread.sleep(DURATION);
-        assertTrue(mWifiManager.isWifiEnabled());
+        assertThat(mWifiManager.isWifiEnabled()).isTrue();
         mMySync.expectedState = STATE_NULL;
     }
 
@@ -123,31 +125,19 @@
             // skip the test if WiFi is not supported
             return;
         }
+
+        // wait for Wifi to be connected
+        PollingCheck.check(
+                "Wifi not connected - Please ensure there is a saved network in range of this "
+                        + "device",
+                20000,
+                () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
+
         // this test case should in Wifi environment
         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
 
-        assertNotNull(wifiInfo);
-        assertNotNull(wifiInfo.toString());
-        SupplicantState.isValidState(wifiInfo.getSupplicantState());
-        WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
-        String ssid = wifiInfo.getSSID();
-        if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) {
-            // Non-hex string should be quoted
-            assertTrue(ssid.charAt(0) == '"');
-            assertTrue(ssid.charAt(ssid.length() - 1) == '"');
-        }
+        testWifiInfoPropertiesWhileConnected(wifiInfo);
 
-        wifiInfo.getBSSID();
-        wifiInfo.getFrequency();
-        wifiInfo.getIpAddress();
-        wifiInfo.getLinkSpeed();
-        wifiInfo.getPasspointFqdn();
-        wifiInfo.getPasspointProviderFriendlyName();
-        wifiInfo.getTxLinkSpeedMbps();
-        wifiInfo.getRxLinkSpeedMbps();
-        wifiInfo.getRssi();
-        wifiInfo.getHiddenSSID();
-        wifiInfo.getMacAddress();
         setWifiEnabled(false);
 
         PollingCheck.check("getNetworkId not -1", 20000, new Callable<Boolean>() {
@@ -166,4 +156,55 @@
         });
     }
 
+    private void testWifiInfoPropertiesWhileConnected(WifiInfo wifiInfo) {
+        assertThat(wifiInfo).isNotNull();
+        assertThat(wifiInfo.toString()).isNotNull();
+        SupplicantState.isValidState(wifiInfo.getSupplicantState());
+        WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
+        String ssid = wifiInfo.getSSID();
+        if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) {
+            // Non-hex string should be quoted
+            assertThat(ssid).startsWith("\"");
+            assertThat(ssid).endsWith("\"");
+        }
+
+        assertThat(wifiInfo.getBSSID()).isNotNull();
+        assertThat(wifiInfo.getFrequency()).isGreaterThan(0);
+        assertThat(wifiInfo.getMacAddress()).isNotNull();
+
+        wifiInfo.getRssi();
+        wifiInfo.getIpAddress();
+        wifiInfo.getHiddenSSID();
+        wifiInfo.getScore();
+
+        // null for saved networks
+        assertThat(wifiInfo.getRequestingPackageName()).isNull();
+        assertThat(wifiInfo.getPasspointFqdn()).isNull();
+        assertThat(wifiInfo.getPasspointProviderFriendlyName()).isNull();
+
+        // false for saved networks
+        assertThat(wifiInfo.isEphemeral()).isFalse();
+        assertThat(wifiInfo.isOsuAp()).isFalse();
+        assertThat(wifiInfo.isPasspointAp()).isFalse();
+
+        assertThat(wifiInfo.getWifiStandard()).isAnyOf(
+                ScanResult.WIFI_STANDARD_UNKNOWN,
+                ScanResult.WIFI_STANDARD_LEGACY,
+                ScanResult.WIFI_STANDARD_11N,
+                ScanResult.WIFI_STANDARD_11AC,
+                ScanResult.WIFI_STANDARD_11AX
+        );
+
+        assertThat(wifiInfo.getLostTxPacketsPerSecond()).isAtLeast(0.0);
+        assertThat(wifiInfo.getRetriedTxPacketsPerSecond()).isAtLeast(0.0);
+        assertThat(wifiInfo.getSuccessfulRxPacketsPerSecond()).isAtLeast(0.0);
+        assertThat(wifiInfo.getSuccessfulTxPacketsPerSecond()).isAtLeast(0.0);
+
+        // Can be -1 if link speed is unknown
+        assertThat(wifiInfo.getLinkSpeed()).isAtLeast(-1);
+        assertThat(wifiInfo.getTxLinkSpeedMbps()).isAtLeast(-1);
+        assertThat(wifiInfo.getRxLinkSpeedMbps()).isAtLeast(-1);
+        assertThat(wifiInfo.getMaxSupportedTxLinkSpeedMbps()).isAtLeast(-1);
+        assertThat(wifiInfo.getMaxSupportedRxLinkSpeedMbps()).isAtLeast(-1);
+    }
 }
diff --git a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
index f0c34e3..6214f89 100644
--- a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -56,6 +56,7 @@
     private static final String TAG = CtsNetUtils.class.getSimpleName();
     private static final int DURATION = 10000;
     private static final int SOCKET_TIMEOUT_MS = 2000;
+    private static final int PRIVATE_DNS_PROBE_MS = 1_000;
 
     public static final int HTTP_PORT = 80;
     public static final String TEST_HOST = "connectivitycheck.gstatic.com";
@@ -246,12 +247,16 @@
     }
 
     public void awaitPrivateDnsSetting(@NonNull String msg, @NonNull Network network,
-            @NonNull String server, int timeoutMs) throws InterruptedException {
+            @NonNull String server, int timeoutMs,
+            boolean requiresValidatedServers) throws InterruptedException {
         CountDownLatch latch = new CountDownLatch(1);
         NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
         NetworkCallback callback = new NetworkCallback() {
             @Override
             public void onLinkPropertiesChanged(Network n, LinkProperties lp) {
+                if (requiresValidatedServers && lp.getValidatedPrivateDnsServers().isEmpty()) {
+                    return;
+                }
                 if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) {
                     latch.countDown();
                 }
@@ -260,6 +265,18 @@
         mCm.registerNetworkCallback(request, callback);
         assertTrue(msg, latch.await(timeoutMs, TimeUnit.MILLISECONDS));
         mCm.unregisterNetworkCallback(callback);
+        // Wait some time for NetworkMonitor's private DNS probe to complete. If we do not do
+        // this, then the test could complete before the NetworkMonitor private DNS probe
+        // completes. This would result in tearDown disabling private DNS, and the NetworkMonitor
+        // private DNS probe getting stuck because there are no longer any private DNS servers to
+        // query. This then results in the next test not being able to change the private DNS
+        // setting within the timeout, because the NetworkMonitor thread is blocked in the
+        // private DNS probe. There is no way to know when the probe has completed: because the
+        // network is likely already validated, there is no callback that we can listen to, so
+        // just sleep.
+        if (requiresValidatedServers) {
+            Thread.sleep(PRIVATE_DNS_PROBE_MS);
+        }
     }
 
     /**
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
index 6eabfb0..3867e9f 100755
--- a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<?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.
@@ -18,6 +17,7 @@
           package="android.packageinstaller.admin.cts" >
 
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
     <application android:label="Cts Admin Package Installer Test" android:testOnly="true">
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/packageinstaller/install/AndroidManifest.xml b/tests/tests/packageinstaller/install/AndroidManifest.xml
index eeef252..4ece1a9 100644
--- a/tests/tests/packageinstaller/install/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/install/AndroidManifest.xml
@@ -18,6 +18,7 @@
           package="android.packageinstaller.install.cts" >
 
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
     <application android:label="Cts Package Installer Tests">
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/packageinstaller/nopermission/AndroidManifest.xml b/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
index 321066c..08a7db1 100755
--- a/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
@@ -17,6 +17,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.packageinstaller.nopermission.cts" >
 
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
     <application>
         <uses-library android:name="android.test.runner" />
 
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 09f31d9..9bbc177 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -2764,7 +2764,7 @@
     <permission android:name="android.permission.READ_DEVICE_CONFIG"
         android:protectionLevel="signature|preinstalled" />
 
-    <!-- @SystemApi @hide Allows an application to monitor config settings access.
+    <!-- @hide Allows an application to monitor config settings access.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"
         android:protectionLevel="signature"/>
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
index 061fe38..7228c7c 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
@@ -116,9 +116,9 @@
         assertEquals(1, mResolver.update(fileUri, values, null, null));
         assertStringColumn(fileUri, MediaColumns.DATA, updatedPath);
 
-        // check that inserting a duplicate entry fails
+        // check that inserting a duplicate entry updates previous entry.
         Uri foo = mResolver.insert(allFilesUri, values);
-        assertNull(foo);
+        assertEquals(foo, fileUri);
 
         // Delete the file and observe that the file count decreased.
         assertEquals(1, mResolver.delete(fileUri, null, null));
diff --git a/tests/tests/secure_element/access_control/OWNERS b/tests/tests/secure_element/access_control/OWNERS
index 853b7c3..6c4d2b3 100644
--- a/tests/tests/secure_element/access_control/OWNERS
+++ b/tests/tests/secure_element/access_control/OWNERS
@@ -1,6 +1,5 @@
 # Bug component: 456592
-zachoverflow@google.com
+alisher@google.com
 jackcwyu@google.com
-tokuda@google.com
 georgekgchang@google.com
-jimmychchang@google.com
+zachoverflow@google.com
diff --git a/tests/tests/secure_element/omapi/OWNERS b/tests/tests/secure_element/omapi/OWNERS
index 853b7c3..6c4d2b3 100644
--- a/tests/tests/secure_element/omapi/OWNERS
+++ b/tests/tests/secure_element/omapi/OWNERS
@@ -1,6 +1,5 @@
 # Bug component: 456592
-zachoverflow@google.com
+alisher@google.com
 jackcwyu@google.com
-tokuda@google.com
 georgekgchang@google.com
-jimmychchang@google.com
+zachoverflow@google.com
diff --git a/tests/tests/text/Android.bp b/tests/tests/text/Android.bp
index f3d34bf..2909777 100644
--- a/tests/tests/text/Android.bp
+++ b/tests/tests/text/Android.bp
@@ -16,6 +16,7 @@
     name: "CtsTextTestCases",
     defaults: ["cts_defaults"],
     sdk_version: "test_current",
+    stl: "c++_shared",
 
     srcs: [
         "src/**/*.java",
@@ -38,7 +39,7 @@
 
     jni_libs: [
         "libctstext_jni",
-        "libc++",
+        "libnativehelper_compat_libc++",
     ],
     // Include both the 32 and 64 bit versions of libctstext_jni, where
     // applicable.
diff --git a/tests/tests/text/jni/Android.bp b/tests/tests/text/jni/Android.bp
index 8055f40..7821605 100644
--- a/tests/tests/text/jni/Android.bp
+++ b/tests/tests/text/jni/Android.bp
@@ -14,9 +14,10 @@
 
 cc_library {
     name: "libctstext_jni",
+    sdk_version: "current",
     srcs: [
         "CtsTextJniOnLoad.cpp",
         "android_text_format_cts_NativeTimeFunctions.cpp",
     ],
-    static_libs: ["libnativehelper"],
+    shared_libs: ["libnativehelper_compat_libc++"],
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 5980663..74198582 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -245,23 +245,30 @@
             return;
         }
 
-        assertTrue(mSettings.getAllowFileAccess());
+        // TODO(b/148840827): Uncomment default value assertion when a new version of WebView
+        // where the change happened is dropped in master.
+        // assertFalse("File access should be off by default", mSettings.getAllowFileAccess());
 
+        mSettings.setAllowFileAccess(true);
+        assertTrue("Explicitly setting file access to true should work",
+                mSettings.getAllowFileAccess());
         String fileUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.HELLO_WORLD_URL);
         mOnUiThread.loadUrlAndWaitForCompletion(fileUrl);
-        assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
+        assertEquals("Loading files on the file system should work with file access enabled",
+                TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
 
         fileUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.BR_TAG_URL);
         mSettings.setAllowFileAccess(false);
-        assertFalse(mSettings.getAllowFileAccess());
+        assertFalse("Explicitly setting file access to false should work",
+                mSettings.getAllowFileAccess());
         mOnUiThread.loadUrlAndWaitForCompletion(fileUrl);
-        // android_asset URLs should still be loaded when even with file access
-        // disabled.
-        assertEquals(TestHtmlConstants.BR_TAG_TITLE, mOnUiThread.getTitle());
+        assertEquals(
+                "android_asset URLs should still be loaded when even with file access disabled",
+                TestHtmlConstants.BR_TAG_TITLE, mOnUiThread.getTitle());
 
-        // Files on the file system should not be loaded.
         mOnUiThread.loadUrlAndWaitForCompletion(TestHtmlConstants.LOCAL_FILESYSTEM_URL);
-        assertEquals(TestHtmlConstants.WEBPAGE_NOT_AVAILABLE_TITLE, mOnUiThread.getTitle());
+        assertEquals("Files on the file system should not be loaded with file access disabled",
+                TestHtmlConstants.WEBPAGE_NOT_AVAILABLE_TITLE, mOnUiThread.getTitle());
     }
 
     public void testAccessCacheMode_defaultValue() throws Throwable {
@@ -1060,6 +1067,7 @@
         writeFile("target.html", target);
 
         mSettings.setJavaScriptEnabled(true);
+        mSettings.setAllowFileAccess(true);
         // disable universal access from files
         mSettings.setAllowUniversalAccessFromFileURLs(false);
         mSettings.setAllowFileAccessFromFileURLs(enableXHR);