Merge "Remove BatteryStats testWifiScan" into pi-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 71ada3d..a7121ad 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -46,6 +46,7 @@
 
 $(call add-clean-step, rm -rf $(HOST_OUT_INTERMEDIATES)/EXECUTABLES/vm-tests-tf_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/cts-tradefed_intermediates/com/android/compatibility/SuiteInfo.java)
+$(call add-clean-step, rm -rf $(HOST_OUT)/cts/android-cts/testcases/CtsUiHostTestCases*)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/apps/CameraITS/tests/scene0/test_read_write.py b/apps/CameraITS/tests/scene0/test_read_write.py
new file mode 100644
index 0000000..3c56fba
--- /dev/null
+++ b/apps/CameraITS/tests/scene0/test_read_write.py
@@ -0,0 +1,117 @@
+# Copyright 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os.path
+
+import its.caps
+import its.device
+import its.image
+import its.objects
+
+NAME = os.path.basename(__file__).split('.')[0]
+RTOL_EXP_GAIN = 0.97
+TEST_EXP_RANGE = [1E6, 1E9]  # ns [1ms, 1s]
+
+
+def main():
+    """Test that the device will write/read correct exp/gain values."""
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.manual_sensor(props) and
+                             its.caps.per_frame_control(props))
+
+        # determine capture format
+        debug = its.caps.debug_mode()
+        largest_yuv = its.objects.get_largest_yuv_format(props)
+        if debug:
+            fmt = largest_yuv
+        else:
+            match_ar = (largest_yuv['width'], largest_yuv['height'])
+            fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
+
+        # grab exp/gain ranges from camera
+        sensor_exp_range = props['android.sensor.info.exposureTimeRange']
+        sens_range = props['android.sensor.info.sensitivityRange']
+        print 'sensor e range:', sensor_exp_range
+        print 'sensor s range:', sens_range
+
+        # determine if exposure test range is within sensor reported range
+        exp_range = []
+        if sensor_exp_range[0] < TEST_EXP_RANGE[0]:
+            exp_range.append(TEST_EXP_RANGE[0])
+        else:
+            exp_range.append(sensor_exp_range[0])
+        if sensor_exp_range[1] > TEST_EXP_RANGE[1]:
+            exp_range.append(TEST_EXP_RANGE[1])
+        else:
+            exp_range.append(sensor_exp_range[1])
+
+        # build requests
+        reqs = []
+        index_list = []
+        for exp in exp_range:
+            for sens in sens_range:
+                reqs.append(its.objects.manual_capture_request(sens, exp))
+                index_list.append((exp, sens))
+
+        # take shots
+        caps = cam.do_capture(reqs, fmt)
+
+        # extract exp/sensitivity data
+        data = {}
+        for i, cap in enumerate(caps):
+            e_read = cap['metadata']['android.sensor.exposureTime']
+            s_read = cap['metadata']['android.sensor.sensitivity']
+            data[index_list[i]] = (e_read, s_read)
+
+        # check read/write match across all shots
+        e_failed = []
+        s_failed = []
+        for e_write in exp_range:
+            for s_write in sens_range:
+                (e_read, s_read) = data[(e_write, s_write)]
+                if e_write < e_read or e_read/float(e_write) <= RTOL_EXP_GAIN:
+                    e_failed.append({'e_write': e_write,
+                                     'e_read': e_read,
+                                     's_write': s_write,
+                                     's_read': s_read})
+                if s_write < s_read or s_read/float(s_write) <= RTOL_EXP_GAIN:
+                    s_failed.append({'e_write': e_write,
+                                     'e_read': e_read,
+                                     's_write': s_write,
+                                     's_read': s_read})
+
+        # print results
+        if e_failed:
+            print '\nFAILs for exposure time'
+            for fail in e_failed:
+                print ' e_write: %d, e_read: %d, RTOL: %.2f, ' % (
+                        fail['e_write'], fail['e_read'], RTOL_EXP_GAIN),
+                print 's_write: %d, s_read: %d, RTOL: %.2f' % (
+                        fail['s_write'], fail['s_read'], RTOL_EXP_GAIN)
+        if s_failed:
+            print 'FAILs for sensitivity(ISO)'
+            for fail in s_failed:
+                print 's_write: %d, s_read: %d, RTOL: %.2f, ' % (
+                        fail['s_write'], fail['s_read'], RTOL_EXP_GAIN),
+                print ' e_write: %d, e_read: %d, RTOL: %.2f' % (
+                        fail['e_write'], fail['e_read'], RTOL_EXP_GAIN)
+
+        # assert PASS/FAIL
+        assert not e_failed+s_failed
+
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index e68b8a3..cf30457 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -202,6 +202,9 @@
             img_raw = its.image.convert_capture_to_rgb_image(cap_raw,
                                                              props=props)
             if its.caps.distortion_correction(props):
+                # The intrinsics and distortion coefficients are meant for full
+                # size RAW. Resize back to full size here.
+                img_raw = cv2.resize(img_raw, (0,0), fx=2.0, fy=2.0)
                 # Intrinsic cal is of format: [f_x, f_y, c_x, c_y, s]
                 # [f_x, f_y] is the horizontal and vertical focal lengths,
                 # [c_x, c_y] is the position of the optical axis,
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index faacaf9..bc00d5f 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -454,6 +454,10 @@
             w, h, s, e*NSEC_TO_MSEC, fps)
         caps = cam.do_capture([req]*int(fps*test_length), fmt)
 
+        # Capture a bit more gyro samples for use in
+        # get_best_alignment_offset
+        time.sleep(0.2)
+
         # Get the gyro events.
         print "Reading out sensor events"
         gyro = cam.get_sensor_events()["gyro"]
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index cc95a2a..5a696e0 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -342,6 +342,8 @@
             <meta-data
                 android:name="test_parent"
                 android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+            <meta-data android:name="test_excluded_features"
+                android:value="android.hardware.type.watch" />
         </activity>
 
         <!--
@@ -365,6 +367,8 @@
             <meta-data
                 android:name="test_parent"
                 android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+            <meta-data android:name="test_excluded_features"
+                android:value="android.hardware.type.watch" />
         </activity>
 
         <!--
@@ -388,6 +392,8 @@
             <meta-data
                 android:name="test_parent"
                 android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+            <meta-data android:name="test_excluded_features"
+                android:value="android.hardware.type.watch" />
         </activity>
 
         <!--
@@ -411,6 +417,8 @@
             <meta-data
                 android:name="test_parent"
                 android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+            <meta-data android:name="test_excluded_features"
+                android:value="android.hardware.type.watch" />
         </activity>
 
         <!--
diff --git a/apps/CtsVerifier/res/layout/bt_hid_device.xml b/apps/CtsVerifier/res/layout/bt_hid_device.xml
index 39d9ecd..478fc0e 100644
--- a/apps/CtsVerifier/res/layout/bt_hid_device.xml
+++ b/apps/CtsVerifier/res/layout/bt_hid_device.xml
@@ -14,7 +14,11 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+<LinearLayout
     style="@style/RootLayoutPadding"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -63,3 +67,5 @@
 
   <include layout="@layout/pass_fail_buttons" />
 </LinearLayout>
+
+</ScrollView>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
index 0aa4841..47ea81f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
@@ -71,8 +71,6 @@
         mTestAdapter = new TestAdapter(this, setupTestList());

         ListView listView = (ListView) findViewById(R.id.ble_client_connection_tests);

         listView.setAdapter(mTestAdapter);

-        listView.setEnabled(false);

-        listView.setClickable(false);

     }

 

     @Override

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
index 28d5d1c..bd463af 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
@@ -28,6 +28,9 @@
 import java.io.IOException;
 import java.lang.Math;
 
+import com.android.cts.verifier.sensors.RVCVRecordActivity;
+import com.android.cts.verifier.sensors.RVCVRecordActivity.RecordProcedureControllerCallback;
+
 /** Camera preview class */
 public class RVCVCameraPreview extends SurfaceView implements SurfaceHolder.Callback {
     private static final String TAG = "RVCVCameraPreview";
@@ -37,6 +40,10 @@
     private Camera mCamera;
     private float mAspect;
     private int mRotation;
+    private boolean mCheckStartTest = false;
+    private boolean mPreviewStarted = false;
+
+    private RVCVRecordActivity.RecordProcedureControllerCallback mRecordProcedureControllerCallback;
 
     /**
      * Constructor
@@ -86,27 +93,6 @@
             // preview camera does not exist
             return;
         }
-
-        try {
-            mCamera.setPreviewDisplay(holder);
-            mCamera.startPreview();
-            int v_height = getHeight();
-            int v_width = getWidth();
-            ViewGroup.LayoutParams layout = getLayoutParams();
-            if ( (float)v_height/v_width  >
-                    mAspect) {
-                layout.height = (int)Math.round(v_width * mAspect);
-                layout.width = v_width;
-            }else {
-                layout.width = (int)Math.round(v_height / mAspect);
-                layout.height = v_height;
-            }
-            Log.d(TAG, String.format("Layout (%d, %d) -> (%d, %d)", v_width, v_height,
-                    layout.width, layout.height));
-            setLayoutParams(layout);
-        } catch (IOException e) {
-            if (LOCAL_LOGD) Log.d(TAG, "Error when starting camera preview: " + e.getMessage());
-        }
     }
     /**
      *  SurfaceHolder.Callback
@@ -125,13 +111,68 @@
             // preview surface or camera does not exist
             return;
         }
+        if (adjustLayoutParamsIfNeeded()) {
+            // Wait on next surfaceChanged() call before proceeding
+            Log.d(TAG, "Waiting on surface change before starting preview");
+            return;
+        }
 
-        // stop preview before making changes
-        mCamera.stopPreview();
+        if (mPreviewStarted) {
+            Log.w(TAG, "Re-starting camera preview");
+            if (mCheckStartTest && mRecordProcedureControllerCallback != null) {
+                mRecordProcedureControllerCallback.stopRecordProcedureController();
+            }
+            mCamera.stopPreview();
+            mPreviewStarted = false;
+        }
+        mCheckStartTest = false;
 
         mCamera.setDisplayOrientation(mRotation);
+        try {
+            mCamera.setPreviewDisplay(holder);
+            mCamera.startPreview();
+            mPreviewStarted = true;
+            if (mRecordProcedureControllerCallback != null) {
+                mCheckStartTest = true;
+                mRecordProcedureControllerCallback.startRecordProcedureController();
+            }
+        } catch (IOException e) {
+            if (LOCAL_LOGD) Log.d(TAG, "Error when starting camera preview: " + e.getMessage());
+        }
+    }
 
-        //do the same as if it is created again
-        surfaceCreated(holder);
+    /**
+     * Resize the layout to more closely match the desired aspect ratio, if necessary.
+     *
+     * @return true if we updated the layout params, false if the params look good
+     */
+    private boolean adjustLayoutParamsIfNeeded() {
+        ViewGroup.LayoutParams layoutParams = getLayoutParams();
+        int curWidth = getWidth();
+        int curHeight = getHeight();
+        float curAspect = (float)curHeight / (float)curWidth;
+        float aspectDelta = Math.abs(mAspect - curAspect);
+        if ((aspectDelta / mAspect) >= 0.01) {
+            if (curAspect > mAspect) {
+                layoutParams.height = (int)Math.round(curWidth * mAspect);
+                layoutParams.width = curWidth;
+            } else {
+                layoutParams.height = curHeight;
+                layoutParams.width = (int)Math.round(curHeight / mAspect);
+            }
+
+            if (layoutParams.height != curHeight || layoutParams.width != curWidth) {
+                Log.d(TAG, String.format("Layout (%d, %d) -> (%d, %d)", curWidth, curHeight,
+                        layoutParams.width, layoutParams.height));
+                setLayoutParams(layoutParams);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void setRecordProcedureControllerCallback(
+            RVCVRecordActivity.RecordProcedureControllerCallback callback) {
+        mRecordProcedureControllerCallback = callback;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
index edc8536..8199736 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
@@ -80,6 +80,33 @@
     private final static boolean     LOG_RAW_SENSORS = false;
     private RawSensorLogger          mRawSensorLogger;
 
+    public final RecordProcedureControllerCallback mRecordProcedureControllerCallback =
+            new RecordProcedureControllerCallback() {
+        public void startRecordProcedureController() {
+            startRecordcontroller();
+        }
+        public void stopRecordProcedureController() {
+            stopRecordcontroller();
+        }
+    };
+
+    public void startRecordcontroller() {
+        if (mController != null) {
+            Log.v(TAG, "startRecordcontroller is working. stop it");
+            mController.quit();
+        }
+        Log.v(TAG, "startRecordcontroller");
+        mController = new RecordProcedureController(this);
+    }
+
+    public void stopRecordcontroller() {
+        if (mController != null) {
+            Log.v(TAG, "startRecordcontroller is working. stop it");
+            mController.quit();
+        }
+        Log.v(TAG, "stopRecordcontroller");
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -99,7 +126,9 @@
     @Override
     protected void onPause() {
         super.onPause();
-        mController.quit();
+        if (mController != null) {
+            mController.quit();
+        }
 
         mCameraContext.end();
         endSoundPool();
@@ -131,7 +160,7 @@
      */
     private void init() {
         mCameraContext = new CameraContext();
-        mCameraContext.init();
+        mCameraContext.init(mRecordProcedureControllerCallback);
 
         mCoverManager = new CoverageManager();
         mIndicatorView.setDataProvider(
@@ -147,8 +176,6 @@
         if (LOG_RAW_SENSORS) {
             mRawSensorLogger = new RawSensorLogger(mRecordDir);
         }
-
-        mController = new RecordProcedureController(this);
     }
 
     /**
@@ -381,6 +408,11 @@
         }
     }
 
+    public interface RecordProcedureControllerCallback {
+        public void startRecordProcedureController();
+        public void stopRecordProcedureController();
+    }
+
     /**
      * Camera preview control class
      */
@@ -388,6 +420,7 @@
         private Camera mCamera;
         private CamcorderProfile mProfile;
         private Camera.CameraInfo mCameraInfo;
+        private RVCVCameraPreview mCameraPreview;
 
         private int [] mPreferredProfiles = {
                 CamcorderProfile.QUALITY_480P,  // smaller -> faster
@@ -514,7 +547,7 @@
         /**
          * Setup the camera
          */
-        public void init() {
+        public void init(RVCVRecordActivity.RecordProcedureControllerCallback callback) {
             if (mCamera != null) {
                 double alpha = mCamera.getParameters().getHorizontalViewAngle()*Math.PI/180.0;
                 int width = mProfile.videoFrameWidth;
@@ -523,9 +556,10 @@
                 if (LOCAL_LOGV) Log.v(TAG, "View angle="
                         + mCamera.getParameters().getHorizontalViewAngle() +"  Estimated fx = "+fx);
 
-                RVCVCameraPreview cameraPreview =
+                mCameraPreview =
                         (RVCVCameraPreview) findViewById(R.id.cam_preview);
-                cameraPreview.init(mCamera,
+                mCameraPreview.setRecordProcedureControllerCallback(callback);
+                mCameraPreview.init(mCamera,
                         (float)mProfile.videoFrameWidth/mProfile.videoFrameHeight,
                         mCameraInfo.orientation);
             } else {
@@ -633,13 +667,28 @@
             }
 
             mRecorder = new MediaRecorder();
-            mCamera.unlock();
-            mRecorder.setCamera(mCamera);
+            try {
+                mCamera.unlock();
+            } catch (RuntimeException e) {
+                e.printStackTrace();
+                try {
+                    mRecorder.reset();
+                    mRecorder.release();
+                } catch (RuntimeException ex) {
+                    e.printStackTrace();
+                }
+                return;
+            }
 
-            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-            mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
-
-            mRecorder.setProfile(mProfile);
+            try {
+                mRecorder.setCamera(mCamera);
+                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+                mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
+                mRecorder.setProfile(mProfile);
+            } catch (RuntimeException e) {
+                e.printStackTrace();
+                return;
+            }
 
             try {
                 mRecorder.setOutputFile(getVideoRecFilePath());
@@ -653,9 +702,13 @@
                 mRecorder.start();
             } catch (RuntimeException e) {
                 Log.e(TAG, "Starting recording failed.");
-                mRecorder.reset();
-                mRecorder.release();
-                mCamera.lock();
+                try {
+                    mRecorder.reset();
+                    mRecorder.release();
+                    mCamera.lock();
+                } catch (RuntimeException ex1) {
+                    e.printStackTrace();
+                }
                 return;
             }
             mRunning = true;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
index f1fee31..d89e84e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
@@ -134,7 +134,7 @@
 
                         return null;
                     } catch (Throwable t) {
-                        return  t;
+                        return t;
                     }
                 }
 
@@ -156,39 +156,64 @@
         mStep3Status = view.findViewById(R.id.step_3_status);
         mConfirm = view.findViewById(R.id.telecom_incoming_self_mgd_confirm_answer_button);
         mConfirm.setOnClickListener(v -> {
-            CtsSelfManagedConnectionService ctsSelfConnSvr =
-                    CtsSelfManagedConnectionService.waitForAndGetConnectionService();
-            if (ctsSelfConnSvr == null) {
-                mStep3Status.setImageResource(R.drawable.fs_error);
-                return;
-            }
-            List<CtsConnection> connections = ctsSelfConnSvr.getConnections();
-            if (connections.size() != 1) {
-                mStep3Status.setImageResource(R.drawable.fs_error);
-                return;
-            }
+            try {
+                CtsSelfManagedConnectionService ctsSelfConnSvr =
+                        CtsSelfManagedConnectionService.waitForAndGetConnectionService();
+                if (ctsSelfConnSvr == null) {
+                    mStep3Status.setImageResource(R.drawable.fs_error);
+                    return;
+                }
+                List<CtsConnection> connections = ctsSelfConnSvr.getConnections();
+                if (connections.size() != 1) {
+                    mStep3Status.setImageResource(R.drawable.fs_error);
+                    return;
+                }
 
-            if (connections.get(0).getState() == Connection.STATE_ACTIVE) {
-                connections
-                        .stream()
-                        .forEach((c) -> c.onDisconnect());
-                mStep3Status.setImageResource(R.drawable.fs_good);
-                getPassButton().setEnabled(true);
-            } else {
-                mStep3Status.setImageResource(R.drawable.fs_error);
-            }
+                if (connections.get(0).getState() == Connection.STATE_ACTIVE) {
+                    mStep3Status.setImageResource(R.drawable.fs_good);
+                    getPassButton().setEnabled(true);
+                } else {
+                    mStep3Status.setImageResource(R.drawable.fs_error);
+                }
 
-            // The self-managed connection service should be disconnected, because all of the
-            // self-managed connections are disconnected.
-            if (CtsConnectionService.getConnectionService() != null) {
-                mStep3Status.setImageResource(R.drawable.fs_error);
-                return;
-            }
+                // The self-managed connection service should be disconnected, because all of the
+                // self-managed connections are disconnected.
+                if (CtsConnectionService.getConnectionService() != null) {
+                    mStep3Status.setImageResource(R.drawable.fs_error);
+                    return;
+                }
 
-            PhoneAccountUtils.unRegisterTestSelfManagedPhoneAccount(this);
+                mConfirm.setEnabled(false);
+            } finally {
+                // If some step fails, make sure we cleanup any lingering connections.
+                cleanupConnectionServices();
+            }
         });
 
         mShowUi.setEnabled(false);
         mConfirm.setEnabled(false);
     }
+
+    private void cleanupConnectionServices() {
+        CtsSelfManagedConnectionService ctsSelfConnSvr =
+                CtsSelfManagedConnectionService.getConnectionService();
+        if (ctsSelfConnSvr != null) {
+            ctsSelfConnSvr.getConnections()
+                    .stream()
+                    .forEach((c) -> {
+                        c.onDisconnect();
+                    });
+        }
+
+        CtsConnectionService ctsConnectionService =
+                CtsConnectionService.getConnectionService();
+        if (ctsConnectionService != null) {
+            ctsConnectionService.getConnections()
+                    .stream()
+                    .forEach((c) -> {
+                        c.onDisconnect();
+                    });
+        }
+        PhoneAccountUtils.unRegisterTestSelfManagedPhoneAccount(this);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
index 71495a0..f4542db 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
@@ -72,7 +72,7 @@
             "com.android.cts.verifier.usb.device.USB_PERMISSION";
     private static final String LOG_TAG = UsbDeviceTestActivity.class.getSimpleName();
     private static final int TIMEOUT_MILLIS = 5000;
-    private static final int LARGE_BUFFER_SIZE = 1305049;
+    private static final int LARGE_BUFFER_SIZE = 124619;
 
     private UsbManager mUsbManager;
     private BroadcastReceiver mUsbDeviceConnectionReceiver;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetTestActivity.java
index 25f0a7a..32c4267 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetTestActivity.java
@@ -19,6 +19,8 @@
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
+import com.android.compatibility.common.util.CddTest;
+
 import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorEventListener;
@@ -29,6 +31,7 @@
 /**
  * CTS Verifier case for verifying basic widget framework functionality.
  */
+@CddTest(requirement="3.8.2/C-1-2,C-1-3")
 public class WidgetTestActivity extends PassFailButtons.Activity {
 
     @Override
diff --git a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/DeviceTestCompanion.java b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/DeviceTestCompanion.java
index 0471fc0c..b3e6166 100644
--- a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/DeviceTestCompanion.java
+++ b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/DeviceTestCompanion.java
@@ -35,7 +35,7 @@
  * Companion code for com.android.cts.verifier.usb.device.UsbDeviceTestActivity
  */
 class DeviceTestCompanion extends TestCompanion {
-    private static final int LARGE_BUFFER_SIZE = 1305049;
+    private static final int LARGE_BUFFER_SIZE = 124619;
 
     DeviceTestCompanion(@NonNull Context context, @NonNull TestObserver observer) {
         super(context, observer);
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfDeviceInfo.java
index 6234f0e..b9a9522 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfDeviceInfo.java
@@ -69,7 +69,9 @@
         if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
            return;
         }
-        store.addResult("target_fcm_version",
-                        VintfObject.getTargetFrameworkCompatibilityMatrixVersion());
+        Long version = VintfObject.getTargetFrameworkCompatibilityMatrixVersion();
+        if (version != null) {
+            store.addResult("target_fcm_version", version);
+        }
     }
 }
diff --git a/hostsidetests/appsecurity/Android.mk b/hostsidetests/appsecurity/Android.mk
index babc67f..59ef75e 100644
--- a/hostsidetests/appsecurity/Android.mk
+++ b/hostsidetests/appsecurity/Android.mk
@@ -30,11 +30,12 @@
 LOCAL_CTS_TEST_PACKAGE := android.appsecurity
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_REQUIRED_MODULES := \
 	CtsCorruptApkTests_b71360999 \
-	CtsCorruptApkTests_b71361168
+	CtsCorruptApkTests_b71361168 \
+	CtsCorruptApkTests_b79488511
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
index aa7e4a0..ad98fa2 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
@@ -25,6 +25,7 @@
 
 import static org.junit.Assert.fail;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -75,6 +76,7 @@
      * sniffed from the underlying fstab.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testFeatureConsistent() throws Exception {
         final boolean hasFeature = hasFeature();
         final boolean hasFstab = hasFstab();
@@ -85,6 +87,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testApps() throws Exception {
         if (!isSupportedDevice()) return;
         final String diskId = getAdoptionDisk();
@@ -136,6 +139,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testPrimaryStorage() throws Exception {
         if (!isSupportedDevice()) return;
         final String diskId = getAdoptionDisk();
@@ -236,6 +240,7 @@
      * adopted volumes.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testPackageInstaller() throws Exception {
         if (!isSupportedDevice()) return;
         final String diskId = getAdoptionDisk();
@@ -265,6 +270,7 @@
      * returned at a later time.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testEjected() throws Exception {
         if (!isSupportedDevice()) return;
         final String diskId = getAdoptionDisk();
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
index 02e62d3..3231d0c 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -101,6 +102,7 @@
      * if it is signed with a different certificate.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testSharedUidDifferentCerts() throws Exception {
         Log.i(LOG_TAG, "installing apks with shared uid, but different certs");
         try {
@@ -130,6 +132,7 @@
      * certificate.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testAppUpgradeDifferentCerts() throws Exception {
         Log.i(LOG_TAG, "installing app upgrade with different certs");
         try {
@@ -156,6 +159,7 @@
      * Test that an app cannot access another app's private data.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testAppFailAccessPrivateData() throws Exception {
         Log.i(LOG_TAG, "installing app that attempts to access another app's private data");
         try {
@@ -187,6 +191,7 @@
      * Test that uninstall of an app removes its private data.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testUninstallRemovesData() throws Exception {
         Log.i(LOG_TAG, "Uninstalling app, verifying data is removed.");
         try {
@@ -219,6 +224,7 @@
      * Test that an app cannot instrument another app that is signed with different certificate.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testInstrumentationDiffCert() throws Exception {
         Log.i(LOG_TAG, "installing app that attempts to instrument another app");
         try {
@@ -253,6 +259,7 @@
      * certificate than the app that declared the permission.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testPermissionDiffCert() throws Exception {
         Log.i(LOG_TAG, "installing app that attempts to use permission of another app");
         try {
@@ -290,6 +297,7 @@
      * Tests that an arbitrary file cannot be installed using the 'cmd' command.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testAdbInstallFile() throws Exception {
         String output = getDevice().executeShellCommand(
                 "cmd package install -S 1024 /data/local/tmp/foo.apk");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ApplicationVisibilityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ApplicationVisibilityTest.java
new file mode 100644
index 0000000..08d965c
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ApplicationVisibilityTest.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.appsecurity.cts;
+
+import android.platform.test.annotations.AppModeFull;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests the visibility of installed applications.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class ApplicationVisibilityTest extends BaseAppSecurityTest {
+
+    private static final String TINY_APK = "CtsPkgInstallTinyApp.apk";
+    private static final String TINY_PKG = "android.appsecurity.cts.tinyapp";
+
+    private static final String TEST_WITH_PERMISSION_APK =
+            "CtsApplicationVisibilityCrossUserApp.apk";
+    private static final String TEST_WITH_PERMISSION_PKG =
+            "com.android.cts.applicationvisibility";
+
+    private int[] mUsers;
+    private String mOldVerifierValue;
+
+    @Before
+    public void setUpPackage() throws Exception {
+        mUsers = Utils.prepareMultipleUsers(getDevice(), 3);
+        mOldVerifierValue =
+                getDevice().executeShellCommand("settings get global package_verifier_enable");
+        getDevice().executeShellCommand("settings put global package_verifier_enable 0");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        getDevice().uninstallPackage(TEST_WITH_PERMISSION_PKG);
+        getDevice().uninstallPackage(TINY_PKG);
+        getDevice().executeShellCommand("settings put global package_verifier_enable "
+                + mOldVerifierValue);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot be granted INTERACT_ACROSS_USERS")
+    public void testPackageListCrossUserGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        final String grantCmd = "pm grant"
+                + " com.android.cts.applicationvisibility"
+                + " android.permission.INTERACT_ACROSS_USERS";
+        getDevice().executeShellCommand(grantCmd);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_currentUser",
+                testUserId);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_anyUserCrossUserGrant",
+                testUserId);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot see any other application")
+    public void testPackageListCrossUserNoGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_currentUser",
+                testUserId);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_anyUserCrossUserNoGrant",
+                testUserId);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot be granted INTERACT_ACROSS_USERS")
+    public void testPackageListOtherUserCrossUserGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+        final Map<String, String> testArgs = new HashMap<>();
+        testArgs.put("testUser", Integer.toString(installUserId));
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        final String grantCmd = "pm grant"
+                + " com.android.cts.applicationvisibility"
+                + " android.permission.INTERACT_ACROSS_USERS";
+        getDevice().executeShellCommand(grantCmd);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_otherUserGrant",
+                testUserId,
+                testArgs);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot see any other application")
+    public void testPackageListOtherUserCrossUserNoGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+        final Map<String, String> testArgs = new HashMap<>();
+        testArgs.put("testUser", Integer.toString(installUserId));
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testPackageVisibility_otherUserNoGrant",
+                testUserId,
+                testArgs);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot be granted INTERACT_ACROSS_USERS")
+    public void testApplicationListCrossUserGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        final String grantCmd = "pm grant"
+                + " com.android.cts.applicationvisibility"
+                + " android.permission.INTERACT_ACROSS_USERS";
+        getDevice().executeShellCommand(grantCmd);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_currentUser",
+                testUserId);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_anyUserCrossUserGrant",
+                testUserId);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot see any other application")
+    public void testApplicationListCrossUserNoGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_currentUser",
+                testUserId);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_anyUserCrossUserNoGrant",
+                testUserId);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot be granted INTERACT_ACROSS_USERS")
+    public void testApplicationListOtherUserCrossUserGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+        final Map<String, String> testArgs = new HashMap<>();
+        testArgs.put("testUser", Integer.toString(installUserId));
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        final String grantCmd = "pm grant"
+                + " com.android.cts.applicationvisibility"
+                + " android.permission.INTERACT_ACROSS_USERS";
+        getDevice().executeShellCommand(grantCmd);
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_otherUserGrant",
+                testUserId,
+                testArgs);
+    }
+
+    @Test
+    @AppModeFull(reason = "instant applications cannot see any other application")
+    public void testApplicationListOtherUserCrossUserNoGrant() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+
+        final int installUserId = mUsers[1];
+        final int testUserId = mUsers[2];
+        final Map<String, String> testArgs = new HashMap<>();
+        testArgs.put("testUser", Integer.toString(installUserId));
+
+        installTestAppForUser(TINY_APK, installUserId);
+        installTestAppForUser(TEST_WITH_PERMISSION_APK, testUserId);
+
+        Utils.runDeviceTests(
+                getDevice(),
+                TEST_WITH_PERMISSION_PKG,
+                ".ApplicationVisibilityCrossUserTest",
+                "testApplicationVisibility_otherUserNoGrant",
+                testUserId,
+                testArgs);
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java
index f4f6d9e..6830f30 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java
@@ -15,6 +15,7 @@
  */
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -57,12 +58,14 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testBaseClassLoader() throws Exception {
         new InstallMultiple().addApk(APK_BASE).run();
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testBaseClassLoader");
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testFeatureAClassLoader() throws Exception {
         new InstallMultiple().addApk(APK_BASE).addApk(APK_FEATURE_A).run();
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testBaseClassLoader");
@@ -70,6 +73,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testFeatureBClassLoader() throws Exception {
         new InstallMultiple().addApk(APK_BASE).addApk(APK_FEATURE_A).addApk(APK_FEATURE_B).run();
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testBaseClassLoader");
@@ -78,6 +82,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testReceiverClassLoaders() throws Exception {
         new InstallMultiple().addApk(APK_BASE).addApk(APK_FEATURE_A).addApk(APK_FEATURE_B).run();
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testBaseClassLoader");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
index dcbea2a..6849d0c 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
@@ -17,6 +17,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.ITestDevice;
@@ -34,9 +35,11 @@
  * Set of tests that verify that corrupt APKs are properly rejected by PackageManager and
  * do not cause the system to crash.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class CorruptApkTests extends DeviceTestCase implements IBuildReceiver {
     private final String B71360999_PKG = "com.android.appsecurity.b71360999";
-    private final String B71361168_PKG = "com.example.helloworld";
+    private final String B71361168_PKG = "com.android.appsecurity.b71361168";
+    private final String B79488511_PKG = "com.android.appsecurity.b79488511";
 
     private IBuildInfo mBuildInfo;
 
@@ -51,6 +54,7 @@
         super.setUp();
         uninstall(B71360999_PKG);
         uninstall(B71361168_PKG);
+        uninstall(B79488511_PKG);
     }
 
     @After
@@ -59,6 +63,7 @@
         super.tearDown();
         uninstall(B71360999_PKG);
         uninstall(B71361168_PKG);
+        uninstall(B79488511_PKG);
     }
 
     /** Uninstall the apk if the test failed previously. */
@@ -70,11 +75,11 @@
     }
 
     /**
-     * Tests that apks described in b/71360999 do not install successfully nor cause
+     * Tests that apks described in b/71360999 do not install successfully.
      */
     public void testFailToInstallCorruptStringPoolHeader_b71360999() throws Exception {
         final String APK_PATH = "CtsCorruptApkTests_b71360999.apk";
-        assertFailsToInstall(APK_PATH, B71360999_PKG);
+        assertInstallNoFatalError(APK_PATH, B71360999_PKG);
     }
 
     /**
@@ -82,14 +87,22 @@
      */
     public void testFailToInstallCorruptStringPoolHeader_b71361168() throws Exception {
         final String APK_PATH = "CtsCorruptApkTests_b71361168.apk";
-        assertFailsToInstall(APK_PATH, B71361168_PKG);
+        assertInstallNoFatalError(APK_PATH, B71361168_PKG);
     }
 
     /**
-     * Assert that the app fails to install and the reason for failing is not caused by a buffer
-     * overflow nor a out of bounds read.
+     * Tests that apks described in b/79488511 do not install successfully.
+     */
+    public void testFailToInstallCorruptStringPoolHeader_b79488511() throws Exception {
+        final String APK_PATH = "CtsCorruptApkTests_b79488511.apk";
+        assertInstallNoFatalError(APK_PATH, B79488511_PKG);
+    }
+
+    /**
+     * Assert that installing the app does not cause a native error caused by a buffer overflow
+     * or an out-of-bounds read.
      **/
-    private void assertFailsToInstall(String filename, String pkg) throws Exception {
+    private void assertInstallNoFatalError(String filename, String pkg) throws Exception {
         ITestDevice device = getDevice();
         device.clearLogcat();
 
@@ -97,9 +110,12 @@
                 new CompatibilityBuildHelper(mBuildInfo).getTestFile(filename),
                 true /*reinstall*/);
 
-        assertThat(result).isNotNull();
-        assertThat(result).isNotEmpty();
-        assertThat(device.getInstalledPackageNames()).doesNotContain(pkg);
+        // Starting from P, corrupt apks should always fail to install
+        if (device.getApiLevel() >= 28) {
+            assertThat(result).isNotNull();
+            assertThat(result).isNotEmpty();
+            assertThat(device.getInstalledPackageNames()).doesNotContain(pkg);
+        }
 
         // This catches if the device fails to install the app because a segmentation fault
         // or out of bounds read created by the bug occurs
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index 7ba2eb9..8a781c6 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.ddmlib.AdbCommandRejectedException;
 import com.android.ddmlib.CollectingOutputReceiver;
 import com.android.ddmlib.Log;
@@ -79,6 +80,7 @@
      * Automotive devices MUST support native FBE.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testAutomotiveNativeFbe() throws Exception {
         if (!isSupportedDevice()) {
             Log.v(TAG, "Device not supported; skipping test");
@@ -96,6 +98,7 @@
      * If device has native FBE, verify lifecycle.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testDirectBootNative() throws Exception {
         if (!isSupportedDevice()) {
             Log.v(TAG, "Device not supported; skipping test");
@@ -112,6 +115,7 @@
      * If device doesn't have native FBE, enable emulation and verify lifecycle.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testDirectBootEmulated() throws Exception {
         if (!isSupportedDevice()) {
             Log.v(TAG, "Device not supported; skipping test");
@@ -128,6 +132,7 @@
      * If device doesn't have native FBE, verify normal lifecycle.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testDirectBootNone() throws Exception {
         if (!isSupportedDevice()) {
             Log.v(TAG, "Device not supported; skipping test");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
index 6f3b8cd..6530e96 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -16,12 +16,14 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 
 /**
  * Set of tests that verify behavior of
  * {@link android.provider.DocumentsContract} and related intents.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class DocumentsTest extends DocumentsTestCase {
     private static final String PROVIDER_PKG = "com.android.cts.documentprovider";
     private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 1b67135..53ec3d4 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -33,6 +34,7 @@
 /**
  * Tests for ephemeral packages.
  */
+@AppModeFull // Already handles instant installs when needed.
 public class EphemeralTest extends DeviceTestCase
         implements IAbiReceiver, IBuildReceiver {
 
@@ -118,9 +120,14 @@
         mBuildInfo = buildInfo;
     }
 
+    @Override
     public void setUp() throws Exception {
         super.setUp();
 
+        if (isDeviceUnsupported()) {
+            return;
+        }
+
         Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mBuildInfo);
@@ -130,27 +137,45 @@
     }
 
     public void tearDown() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         uninstallTestPackages();
         super.tearDown();
     }
 
     public void testNormalQuery() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(NORMAL_PKG, TEST_CLASS, "testQuery");
     }
 
     public void testNormalStartNormal() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(NORMAL_PKG, TEST_CLASS, "testStartNormal");
     }
 
     public void testNormalStartEphemeral() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(NORMAL_PKG, TEST_CLASS, "testStartEphemeral");
     }
 
     public void testEphemeralQuery() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testQuery");
     }
 
     public void testEphemeralStartNormal() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartNormal");
     }
 
@@ -158,55 +183,100 @@
     // avoid sharing state. once an instant app is exposed to a component, it's
     // exposed until the device restarts or the instant app is removed.
     public void testEphemeralStartExposed01() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed01");
     }
     public void testEphemeralStartExposed02() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed02");
     }
     public void testEphemeralStartExposed03() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed03");
     }
     public void testEphemeralStartExposed04() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed04");
     }
     public void testEphemeralStartExposed05() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed05");
     }
     public void testEphemeralStartExposed06() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed06");
     }
     public void testEphemeralStartExposed07() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed07");
     }
     public void testEphemeralStartExposed08() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed08");
     }
     public void testEphemeralStartExposed09() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed09");
     }
     public void testEphemeralStartExposed10() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed10");
     }
 
     public void testEphemeralStartEphemeral() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testStartEphemeral");
     }
 
     public void testEphemeralGetInstaller01() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         installEphemeralApp(EPHEMERAL_1_APK, "com.android.cts.normalapp");
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testGetInstaller01");
     }
     public void testEphemeralGetInstaller02() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         installApp(NORMAL_APK, "com.android.cts.normalapp");
         installEphemeralApp(EPHEMERAL_1_APK, "com.android.cts.normalapp");
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testGetInstaller02");
     }
     public void testEphemeralGetInstaller03() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         installApp(NORMAL_APK, "com.android.cts.normalapp");
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testGetInstaller03");
     }
 
     public void testExposedSystemActivities() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         for (Map<String, String> testArgs : EXPECTED_EXPOSED_INTENTS) {
             final boolean exposed = isIntentExposed(testArgs);
             if (exposed) {
@@ -218,31 +288,52 @@
     }
 
     public void testBuildSerialUnknown() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testBuildSerialUnknown");
     }
 
     public void testPackageInfo() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testPackageInfo");
     }
 
     public void testActivityInfo() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testActivityInfo");
     }
 
     public void testWebViewLoads() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, WEBVIEW_TEST_CLASS, "testWebViewLoads");
     }
 
     public void testInstallPermissionNotGranted() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testInstallPermissionNotGranted");
     }
 
     public void testInstallPermissionGranted() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testInstallPermissionGranted");
     }
 
     /** Test for android.permission.INSTANT_APP_FOREGROUND_SERVICE */
     public void testStartForegrondService() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         // Make sure the test package does not have INSTANT_APP_FOREGROUND_SERVICE
         getDevice().executeShellCommand("cmd package revoke " + EPHEMERAL_1_PKG
                         + " android.permission.INSTANT_APP_FOREGROUND_SERVICE");
@@ -251,46 +342,73 @@
 
     /** Test for android.permission.RECORD_AUDIO */
     public void testRecordAudioPermission() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testRecordAudioPermission");
     }
 
     /** Test for android.permission.CAMERA */
     public void testCameraPermission() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testCameraPermission");
     }
 
     /** Test for android.permission.READ_PHONE_NUMBERS */
     public void testReadPhoneNumbersPermission() throws Exception {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testReadPhoneNumbersPermission");
     }
 
     /** Test for android.permission.ACCESS_COARSE_LOCATION */
     public void testAccessCoarseLocationPermission() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testAccessCoarseLocationPermission");
     }
 
     /** Test for android.permission.NETWORK */
     public void testInternetPermission() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testInternetPermission");
     }
 
     /** Test for android.permission.VIBRATE */
     public void testVibratePermission() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testVibratePermission");
     }
 
     /** Test for android.permission.WAKE_LOCK */
     public void testWakeLockPermission() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testWakeLockPermission");
     }
 
     /** Test for search manager */
     public void testGetSearchableInfo() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testGetSearchableInfo");
     }
 
     /** Test for upgrade from instant --> full */
     public void testInstantAppUpgrade() throws Throwable {
+        if (isDeviceUnsupported()) {
+            return;
+        }
         installEphemeralApp(UPGRADED_APK);
         runDeviceTests(UPGRADED_PKG, TEST_CLASS, "testInstantApplicationWritePreferences");
         runDeviceTests(UPGRADED_PKG, TEST_CLASS, "testInstantApplicationWriteFile");
@@ -315,6 +433,19 @@
         return testArgs;
     }
 
+    private static final String[] sUnsupportedFeatures = {
+            "feature:android.hardware.type.watch",
+            "android.hardware.type.embedded",
+    };
+    private boolean isDeviceUnsupported() throws Exception {
+        for (String unsupportedFeature : sUnsupportedFeatures) {
+            if (getDevice().hasFeature(unsupportedFeature)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private boolean isIntentExposed(Map<String, String> testArgs)
             throws DeviceNotAvailableException {
         final StringBuffer command = new StringBuffer();
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index 3ba96ea..c2a0531 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -78,6 +79,7 @@
      * Verify that app with no external storage permissions works correctly.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testExternalStorageNone() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -101,6 +103,7 @@
      * correctly.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testExternalStorageRead() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -124,6 +127,7 @@
      * correctly.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testExternalStorageWrite() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -146,6 +150,7 @@
      * directories belonging to other apps, and those apps can read.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testExternalStorageGifts() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -180,6 +185,7 @@
      * isolated storage.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testMultiUserStorageIsolated() throws Exception {
         try {
             if (mUsers.length == 1) {
@@ -226,6 +232,7 @@
      * when apps with r/w permission levels move around their files.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testMultiViewMoveConsistency() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -269,6 +276,7 @@
 
     /** Verify that app without READ_EXTERNAL can play default URIs in external storage. */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testExternalStorageReadDefaultUris() throws Exception {
         try {
             wipePrimaryExternalStorage();
@@ -305,6 +313,7 @@
      * tool to read/write files in those locations.
      */
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testSecondaryUsersInaccessible() throws Exception {
         List<String> mounts = new ArrayList<>();
         for (String line : getDevice().executeShellCommand("cat /proc/mounts").split("\n")) {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
index 4609e8a..b6cd29d 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -29,6 +30,7 @@
 /**
  * Tests for ephemeral packages.
  */
+@AppModeFull // Already handles instant installs when needed.
 public class InstantAppUserTest extends DeviceTestCase
         implements IAbiReceiver, IBuildReceiver {
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
index 51fa77b..c276d66 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -25,6 +26,7 @@
 /**
  * Tests for the instant cookie APIs
  */
+@AppModeFull // Already handles instant installs when needed.
 public class InstantCookieHostTest extends DeviceTestCase implements IBuildReceiver {
     private static final String INSTANT_COOKIE_APP_APK = "CtsInstantCookieApp.apk";
     private static final String INSTANT_COOKIE_APP_PKG = "test.instant.cookie";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
index 8795fe8..dc08b6c 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
@@ -15,10 +15,12 @@
  */
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
+@AppModeFull // TODO: Needs porting to instant
 public class IsolatedSplitsTests extends DeviceTestCase implements IBuildReceiver {
     private static final String PKG = "com.android.cts.isolatedsplitapp";
     private static final String TEST_CLASS = PKG + ".SplitAppTest";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
index 03a1189..28061f6 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestResult.TestStatus;
@@ -36,6 +37,7 @@
 /**
  * Tests for Keyset based features.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class KeySetHostTest extends DeviceTestCase implements IBuildReceiver {
 
     private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/MajorVersionTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/MajorVersionTest.java
index 15c3d3c..e1d913e 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/MajorVersionTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/MajorVersionTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -27,6 +28,7 @@
 /**
  * Test that install of apps using major version codes is being handled properly.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class MajorVersionTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
     private static final String PKG = "com.android.cts.majorversion";
     private static final String APK_000000000000ffff = "CtsMajorVersion000000000000ffff.apk";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
index cf903db..b4d6877 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
@@ -15,11 +15,13 @@
  */
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
+@AppModeFull // TODO: Needs porting to instant
 public class OverlayHostTest extends DeviceTestCase implements IBuildReceiver {
     private static final String PKG = "com.android.cts.overlayapp";
     private static final String APK = "CtsOverlayApp.apk";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageResolutionHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageResolutionHostTest.java
index 680798a..8e409bb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageResolutionHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageResolutionHostTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -52,6 +53,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testResolveOrderedActivity() throws Exception {
         getDevice().installPackage(mBuildHelper.getTestFile(TINY_APK), true);
         Utils.runDeviceTests(getDevice(), TINY_PKG,
@@ -60,6 +62,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testResolveOrderedService() throws Exception {
         getDevice().installPackage(mBuildHelper.getTestFile(TINY_APK), true);
         Utils.runDeviceTests(getDevice(), TINY_PKG,
@@ -68,6 +71,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testResolveOrderedReceiver() throws Exception {
         getDevice().installPackage(mBuildHelper.getTestFile(TINY_APK), true);
         Utils.runDeviceTests(getDevice(), TINY_PKG,
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
index 5bb70d1..ffce613 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
@@ -66,6 +67,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testUninstalledPackageVisibility() throws Exception {
         if (!mSupportsMultiUser) {
             return;
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
index e4b0f09..3d270b90 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
@@ -30,6 +31,7 @@
  * Set of tests that verify behavior of runtime permissions, including both
  * dynamic granting and behavior of legacy apps.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class PermissionsHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
     private static final String USES_PERMISSION_PKG = "com.android.cts.usepermission";
     private static final String ESCALATE_PERMISSION_PKG = "com.android.cts.escalate.permission";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
index 48a8ac7..83a22cf 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.SecurityTest;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
@@ -36,6 +37,7 @@
 /**
  * Tests for APK signature verification during installation.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class PkgInstallSignatureVerificationTest extends DeviceTestCase implements IBuildReceiver {
 
     private static final String TEST_PKG = "android.appsecurity.cts.tinyapp";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
index 66cee05..5f59d34 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.tradefed.build.IBuildInfo;
@@ -31,6 +32,7 @@
 /**
  * Tests that verify intent filters.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class PrivilegedUpdateTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
     private static final String TAG = "PrivilegedUpdateTests";
     private static final String SHIM_PKG = "com.android.cts.priv.ctsshim";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
index 96992bf..b40d806 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
@@ -16,9 +16,12 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 /**
  * Set of tests that verify behavior of the Scoped Directory access API.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class ScopedDirectoryAccessTest extends DocumentsTestCase {
 
     public void testInvalidPath() throws Exception {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
index acec1fb..f8841cb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
@@ -16,6 +16,8 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.testtype.DeviceTestCase;
@@ -35,6 +37,7 @@
 
     static final String PKG = "com.android.cts.splitapp";
     static final String CLASS = PKG + ".SplitAppTest";
+    static final String CLASS_NO_RESTART = PKG_NO_RESTART + ".NoRestartTest";
 
     static final String APK = "CtsSplitApp.apk";
 
@@ -111,19 +114,51 @@
         getDevice().uninstallPackage(PKG_NO_RESTART);
     }
 
-    public void testSingleBase() throws Exception {
-        new InstallMultiple().addApk(APK).run();
+    @AppModeInstant
+    public void testSingleBaseInstant() throws Exception {
+        testSingleBase(true);
+    }
+
+    @AppModeFull
+    public void testSingleBaseFull() throws Exception {
+        testSingleBase(false);
+    }
+
+    private void testSingleBase(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testSingleBase");
     }
 
-    public void testDensitySingle() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+    @AppModeInstant
+    public void testDensitySingleInstant() throws Exception {
+        testDensitySingle(true);
+    }
+
+    @AppModeFull
+    public void testDensitySingleFull() throws Exception {
+        testDensitySingle(false);
+    }
+
+    private void testDensitySingle(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_mdpi)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testDensitySingle");
     }
 
-    public void testDensityAll() throws Exception {
+    @AppModeInstant
+    public void testDensityAllInstant() throws Exception {
+        testDensityAll(true);
+    }
+
+    @AppModeFull
+    public void testDensityAllFull() throws Exception {
+        testDensityAll(false);
+    }
+
+    private void testDensityAll(boolean instant) throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_mdpi).addApk(APK_hdpi).addApk(APK_xhdpi)
-                .addApk(APK_xxhdpi).run();
+                .addApk(APK_xxhdpi).addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testDensityAll");
     }
 
@@ -131,12 +166,28 @@
      * Install first with low-resolution resources, then add a split that offers
      * higher-resolution resources.
      */
-    public void testDensityBest() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+    @AppModeInstant
+    public void testDensityBestInstant() throws Exception {
+        testDensityBest(true);
+    }
+
+    /**
+     * Install first with low-resolution resources, then add a split that offers
+     * higher-resolution resources.
+     */
+    @AppModeFull
+    public void testDensityBestFull() throws Exception {
+        testDensityBest(false);
+    }
+
+    private void testDensityBest(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_mdpi)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testDensityBest1");
 
         // Now splice in an additional split which offers better resources
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testDensityBest2");
     }
 
@@ -144,13 +195,39 @@
      * Verify that an API-based split can change enabled/disabled state of
      * manifest elements.
      */
-    public void testApi() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+    @AppModeInstant
+    public void testApiInstant() throws Exception {
+        testApi(true);
+    }
+
+    /**
+     * Verify that an API-based split can change enabled/disabled state of
+     * manifest elements.
+     */
+    @AppModeFull
+    public void testApiFull() throws Exception {
+        testApi(false);
+    }
+
+    private void testApi(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testApi");
     }
 
-    public void testLocale() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr).run();
+    @AppModeInstant
+    public void testLocaleInstant() throws Exception {
+        testLocale(true);
+    }
+
+    @AppModeFull
+    public void testLocaleFull() throws Exception {
+        testLocale(false);
+    }
+
+    private void testLocale(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testLocale");
     }
 
@@ -158,12 +235,27 @@
      * Install test app with <em>single</em> split that exactly matches the
      * currently active ABI. This also explicitly forces ABI when installing.
      */
-    public void testNativeSingle() throws Exception {
+    @AppModeInstant
+    public void testNativeSingleInstant() throws Exception {
+        testNativeSingle(true);
+    }
+
+    /**
+     * Install test app with <em>single</em> split that exactly matches the
+     * currently active ABI. This also explicitly forces ABI when installing.
+     */
+    @AppModeFull
+    public void testNativeSingleFull() throws Exception {
+        testNativeSingle(false);
+    }
+
+    private void testNativeSingle(boolean instant) throws Exception {
         final String abi = mAbi.getName();
         final String apk = ABI_TO_APK.get(abi);
         assertNotNull("Failed to find APK for ABI " + abi, apk);
 
-        new InstallMultiple().addApk(APK).addApk(apk).run();
+        new InstallMultiple().addApk(APK).addApk(apk)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testNative");
     }
 
@@ -173,12 +265,29 @@
      * installing, instead exercising the system's ability to choose the ABI
      * through inspection of the installed app.
      */
-    public void testNativeSingleNatural() throws Exception {
+    @AppModeInstant
+    public void testNativeSingleNaturalInstant() throws Exception {
+        testNativeSingleNatural(true);
+    }
+
+    /**
+     * Install test app with <em>single</em> split that exactly matches the
+     * currently active ABI. This variant <em>does not</em> force the ABI when
+     * installing, instead exercising the system's ability to choose the ABI
+     * through inspection of the installed app.
+     */
+    @AppModeFull
+    public void testNativeSingleNaturalFull() throws Exception {
+        testNativeSingleNatural(false);
+    }
+
+    private void testNativeSingleNatural(boolean instant) throws Exception {
         final String abi = mAbi.getName();
         final String apk = ABI_TO_APK.get(abi);
         assertNotNull("Failed to find APK for ABI " + abi, apk);
 
-        new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
+        new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testNative");
     }
 
@@ -186,13 +295,18 @@
      * Install test app with <em>all</em> possible ABI splits. This also
      * explicitly forces ABI when installing.
      */
-    public void testNativeAll() throws Exception {
-        final InstallMultiple inst = new InstallMultiple().addApk(APK);
-        for (String apk : ABI_TO_APK.values()) {
-            inst.addApk(apk);
-        }
-        inst.run();
-        runDeviceTests(PKG, CLASS, "testNative");
+    @AppModeInstant
+    public void testNativeAllInstant() throws Exception {
+        testNativeAll(true, false);
+    }
+
+    /**
+     * Install test app with <em>all</em> possible ABI splits. This also
+     * explicitly forces ABI when installing.
+     */
+    @AppModeFull
+    public void testNativeAllFull() throws Exception {
+        testNativeAll(false, false);
     }
 
     /**
@@ -201,88 +315,269 @@
      * system's ability to choose the ABI through inspection of the installed
      * app.
      */
-    public void testNativeAllNatural() throws Exception {
-        final InstallMultiple inst = new InstallMultiple().useNaturalAbi().addApk(APK);
+    @AppModeInstant
+    public void testNativeAllNaturalInstant() throws Exception {
+        testNativeAll(true, true);
+    }
+
+    /**
+     * Install test app with <em>all</em> possible ABI splits. This variant
+     * <em>does not</em> force the ABI when installing, instead exercising the
+     * system's ability to choose the ABI through inspection of the installed
+     * app.
+     */
+    @AppModeFull
+    public void testNativeAllNaturalFull() throws Exception {
+        testNativeAll(false, true);
+    }
+
+    private void testNativeAll(boolean instant, boolean natural) throws Exception {
+        final InstallMultiple inst = new InstallMultiple().addApk(APK);
         for (String apk : ABI_TO_APK.values()) {
             inst.addApk(apk);
         }
+        if (instant) {
+            inst.addArg("--instant");
+        }
+        if (natural) {
+            inst.useNaturalAbi();
+        }
         inst.run();
         runDeviceTests(PKG, CLASS, "testNative");
     }
 
-    public void testDuplicateBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK).runExpectingFailure();
+    @AppModeInstant
+    public void testDuplicateBaseInstant() throws Exception {
+        testDuplicateBase(true);
     }
 
+    @AppModeFull
+    public void testDuplicateBaseFull() throws Exception {
+        testDuplicateBase(false);
+    }
+
+    private void testDuplicateBase(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
     public void testDuplicateSplit() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).addApk(APK_v7).runExpectingFailure();
+        testDuplicateSplit(true);
     }
 
-    public void testDiffCert() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+    @AppModeFull
+    public void testDuplicateSplitFull() throws Exception {
+        testDuplicateSplit(false);
     }
 
-    public void testDiffCertInherit() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+    private void testDuplicateSplit(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7).addApk(APK_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
     }
 
-    public void testDiffVersion() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+    @AppModeInstant
+    public void testDiffCertInstant() throws Exception {
+        testDiffCert(true);
     }
 
-    public void testDiffVersionInherit() throws Exception {
-        new InstallMultiple().addApk(APK).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+    @AppModeFull
+    public void testDiffCertFull() throws Exception {
+        testDiffCert(false);
     }
 
-    public void testDiffRevision() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
+    private void testDiffCert(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_CERT_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
+    public void testDiffCertInheritInstant() throws Exception {
+        testDiffCertInherit(true);
+    }
+
+    @AppModeFull
+    public void testDiffCertInheritFull() throws Exception {
+        testDiffCertInherit(false);
+    }
+
+    private void testDiffCertInherit(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK) .addArg(instant ? "--instant" : "").run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_CERT_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
+    public void testDiffVersionInstant() throws Exception {
+        testDiffVersion(true);
+    }
+
+    @AppModeFull
+    public void testDiffVersionFull() throws Exception {
+        testDiffVersion(false);
+    }
+
+    private void testDiffVersion(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_VERSION_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
+    public void testDiffVersionInheritInstant() throws Exception {
+        testDiffVersionInherit(true);
+    }
+
+    @AppModeFull
+    public void testDiffVersionInheritFull() throws Exception {
+        testDiffVersionInherit(false);
+    }
+
+    private void testDiffVersionInherit(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addArg(instant ? "--instant" : "").run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
+    public void testDiffRevisionInstant() throws Exception {
+        testDiffRevision(true);
+    }
+
+    @AppModeFull
+    public void testDiffRevisionFull() throws Exception {
+        testDiffRevision(false);
+    }
+
+    private void testDiffRevision(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testRevision0_12");
     }
 
-    public void testDiffRevisionInheritBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+    @AppModeInstant
+    public void testDiffRevisionInheritBaseInstant() throws Exception {
+        testDiffRevisionInheritBase(true);
+    }
+
+    @AppModeFull
+    public void testDiffRevisionInheritBaseFull() throws Exception {
+        testDiffRevisionInheritBase(false);
+    }
+
+    private void testDiffRevisionInheritBase(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testRevision0_0");
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION_v7).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testRevision0_12");
     }
 
-    public void testDiffRevisionInheritSplit() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+    @AppModeInstant
+    public void testDiffRevisionInheritSplitInstant() throws Exception {
+        testDiffRevisionInheritSplit(true);
+    }
+
+    @AppModeFull
+    public void testDiffRevisionInheritSplitFull() throws Exception {
+        testDiffRevisionInheritSplit(false);
+    }
+
+    private void testDiffRevisionInheritSplit(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testRevision0_0");
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION).run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testRevision12_0");
     }
 
-    public void testDiffRevisionDowngrade() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
-        new InstallMultiple().inheritFrom(PKG).addApk(APK_v7).runExpectingFailure();
+    @AppModeInstant
+    public void testDiffRevisionDowngradeInstant() throws Exception {
+        testDiffRevisionDowngrade(true);
     }
 
-    public void testFeatureBase() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
+    @AppModeFull
+    public void testDiffRevisionDowngradeFull() throws Exception {
+        testDiffRevisionDowngrade(false);
+    }
+
+    private void testDiffRevisionDowngrade(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7)
+                .addArg(instant ? "--instant" : "").run();
+        new InstallMultiple().inheritFrom(PKG).addApk(APK_v7)
+                .addArg(instant ? "--instant" : "").runExpectingFailure();
+    }
+
+    @AppModeInstant
+    public void testFeatureBaseInstant() throws Exception {
+        testFeatureBase(true);
+    }
+
+    @AppModeFull
+    public void testFeatureBaseFull() throws Exception {
+        testFeatureBase(false);
+    }
+
+    private void testFeatureBase(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_FEATURE)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testFeatureBase");
     }
 
-    public void testFeatureApi() throws Exception {
-        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
+    @AppModeInstant
+    public void testFeatureApiInstant() throws Exception {
+        testFeatureApiInstant(true);
+    }
+
+    @AppModeFull
+    public void testFeatureApiFull() throws Exception {
+        testFeatureApiInstant(false);
+    }
+
+    private void testFeatureApiInstant(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testFeatureApi");
     }
 
+    @AppModeFull
+    @AppModeInstant
     public void testInheritUpdatedBase() throws Exception {
         // TODO: flesh out this test
     }
 
+    @AppModeFull
+    @AppModeInstant
     public void testInheritUpdatedSplit() throws Exception {
         // TODO: flesh out this test
     }
 
-    public void testFeatureWithoutRestart() throws Exception {
+    @AppModeInstant
+    public void testFeatureWithoutRestartInstant() throws Exception {
+        testFeatureWithoutRestart(true);
+    }
+
+    @AppModeFull
+    public void testFeatureWithoutRestartFull() throws Exception {
+        testFeatureWithoutRestart(false);
+    }
+
+    private void testFeatureWithoutRestart(boolean instant) throws Exception {
         new InstallMultiple().addApk(APK).run();
-        new InstallMultiple().addApk(APK_NO_RESTART_BASE).run();
+
+        new InstallMultiple().addApk(APK_NO_RESTART_BASE)
+                .addArg(instant ? "--instant" : "").run();
+
+        if (instant) {
+            // Poke the full app so it can see the instant app.
+            runDeviceTests(PKG_NO_RESTART, CLASS_NO_RESTART, "testPokeFullApp");
+        }
+
         runDeviceTests(PKG, CLASS, "testBaseInstalled");
+
         new InstallMultiple()
+                .addArg(instant ? "--instant" : "")
                 .addArg("--dont-kill")
                 .inheritFrom(PKG_NO_RESTART)
                 .addApk(APK_NO_RESTART_FEATURE)
@@ -293,10 +588,25 @@
     /**
      * Verify that installing a new version of app wipes code cache.
      */
-    public void testClearCodeCache() throws Exception {
-        new InstallMultiple().addApk(APK).run();
+    @AppModeInstant
+    public void testClearCodeCacheInstant() throws Exception {
+        testClearCodeCache(true);
+    }
+
+    /**
+     * Verify that installing a new version of app wipes code cache.
+     */
+    @AppModeFull
+    public void testClearCodeCacheFull() throws Exception {
+        testClearCodeCache(false);
+    }
+
+    private void testClearCodeCache(boolean instant) throws Exception {
+        new InstallMultiple().addApk(APK)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testCodeCacheWrite");
-        new InstallMultiple().addArg("-r").addApk(APK_DIFF_VERSION).run();
+        new InstallMultiple().addArg("-r").addApk(APK_DIFF_VERSION)
+                .addArg(instant ? "--instant" : "").run();
         runDeviceTests(PKG, CLASS, "testCodeCacheRead");
     }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
index 38f7347..7c64324 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.ddmlib.testrunner.TestResult.TestStatus;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.result.TestDescription;
@@ -73,11 +74,13 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerify() throws Exception {
         Utils.runDeviceTests(getDevice(), PKG_STATS, CLASS_STATS, "testVerify");
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyAppStats() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testAllocate", user);
@@ -96,6 +99,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyAppQuota() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testVerifyQuotaApi", user);
@@ -103,6 +107,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyAppAllocate() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testVerifyAllocateApi", user);
@@ -110,6 +115,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifySummary() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifySummary", user);
@@ -117,6 +123,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyStats() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStats", user);
@@ -124,6 +131,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyStatsMultiple() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testAllocate", user);
@@ -138,6 +146,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyStatsExternal() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternal", user);
@@ -145,6 +154,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyStatsExternalConsistent() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternalConsistent", user);
@@ -152,6 +162,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testVerifyCategory() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyCategory", user);
@@ -159,6 +170,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testCache() throws Exception {
         // To make the cache clearing logic easier to verify, ignore any cache
         // and low space reserved space.
@@ -185,6 +197,7 @@
     }
 
     @Test
+    @AppModeFull // TODO: Needs porting to instant
     public void testFullDisk() throws Exception {
         // Clear all other cached and external storage data to give ourselves a
         // clean slate to test against
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
index 4afeb9bf..a8c3dd9 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
@@ -16,6 +16,7 @@
 
 package android.appsecurity.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -28,6 +29,7 @@
  * Set of tests that verify behavior of runtime permissions, including both
  * dynamic granting and behavior of legacy apps.
  */
+@AppModeFull // TODO: Needs porting to instant
 public class UsesLibraryHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
     private static final String PKG = "com.android.cts.useslibrary";
 
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/Android.mk
similarity index 64%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/Android.mk
index e6ee38f..0668860 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/Android.mk
@@ -12,19 +12,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH := $(call my-dir)
+LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
 
-# Tag this module as a cts test artifact
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
+
+LOCAL_PACKAGE_NAME := CtsApplicationVisibilityCrossUserApp
+
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/AndroidManifest.xml
new file mode 100644
index 0000000..d9a1f36
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.cts.applicationvisibility">
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.applicationvisibility"
+                     android:label="Test to check application visibility for an app with cross user permission."/>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/src/com/android/cts/applicationvisibility/ApplicationVisibilityCrossUserTest.java b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/src/com/android/cts/applicationvisibility/ApplicationVisibilityCrossUserTest.java
new file mode 100644
index 0000000..1737817
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ApplicationVisibilityCrossUserApp/src/com/android/cts/applicationvisibility/ApplicationVisibilityCrossUserTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.applicationvisibility;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class ApplicationVisibilityCrossUserTest {
+    private String TINY_PKG = "android.appsecurity.cts.tinyapp";
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    /** Tests getting installed packages for the current user */
+    @Test
+    public void testPackageVisibility_currentUser() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<PackageInfo> packageList =
+                pm.getInstalledPackagesAsUser(0, mContext.getUserId());
+        assertFalse(isAppInPackageList(TINY_PKG, packageList));
+    }
+
+    /** Tests getting installed packages for all users, with cross user permission granted */
+    @Test
+    public void testPackageVisibility_anyUserCrossUserGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<PackageInfo> packageList =
+                pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
+        assertTrue(isAppInPackageList(TINY_PKG, packageList));
+    }
+
+    /** Tests getting installed packages for all users, with cross user permission revoked */
+    @Test
+    public void testPackageVisibility_anyUserCrossUserNoGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final List<PackageInfo> packageList =
+                    pm.getInstalledPackagesAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
+            fail("Should have received a security exception");
+        } catch (SecurityException ignore) {}
+    }
+
+    /** Tests getting installed packages for another user, with cross user permission granted */
+    @Test
+    public void testPackageVisibility_otherUserGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<PackageInfo> packageList =
+                pm.getInstalledPackagesAsUser(0, getTestUser());
+        assertTrue(isAppInPackageList(TINY_PKG, packageList));
+    }
+
+    /** Tests getting installed packages for another user, with cross user permission revoked */
+    @Test
+    public void testPackageVisibility_otherUserNoGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final List<PackageInfo> packageList =
+                    pm.getInstalledPackagesAsUser(0, getTestUser());
+            fail("Should have received a security exception");
+        } catch (SecurityException ignore) {}
+    }
+
+    /** Tests getting installed applications for the current user */
+    @Test
+    public void testApplicationVisibility_currentUser() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<ApplicationInfo> applicationList =
+                pm.getInstalledApplicationsAsUser(0, mContext.getUserId());
+        assertFalse(isAppInApplicationList(TINY_PKG, applicationList));
+    }
+
+    /** Tests getting installed applications for all users, with cross user permission granted */
+    @Test
+    public void testApplicationVisibility_anyUserCrossUserGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<ApplicationInfo> applicationList =
+                pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
+        assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
+    }
+
+    /** Tests getting installed applications for all users, with cross user permission revoked */
+    @Test
+    public void testApplicationVisibility_anyUserCrossUserNoGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final List<ApplicationInfo> applicationList =
+                    pm.getInstalledApplicationsAsUser(MATCH_KNOWN_PACKAGES, mContext.getUserId());
+            fail("Should have received a security exception");
+        } catch (SecurityException ignore) {}
+    }
+
+    /** Tests getting installed applications for another user, with cross user permission granted */
+    @Test
+    public void testApplicationVisibility_otherUserGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        final List<ApplicationInfo> applicationList =
+                pm.getInstalledApplicationsAsUser(0, getTestUser());
+        assertTrue(isAppInApplicationList(TINY_PKG, applicationList));
+    }
+
+    /** Tests getting installed applications for another user, with cross user permission revoked */
+    @Test
+    public void testApplicationVisibility_otherUserNoGrant() throws Exception {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final List<ApplicationInfo> applicationList =
+                    pm.getInstalledApplicationsAsUser(0, getTestUser());
+            fail("Should have received a security exception");
+        } catch (SecurityException ignore) {}
+    }
+
+    private boolean isAppInPackageList(String packageName,
+            List<PackageInfo> packageList) {
+        for (PackageInfo pkgInfo : packageList) {
+            if (pkgInfo.packageName.equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isAppInApplicationList(
+            String packageName, List<ApplicationInfo> applicationList) {
+        for (ApplicationInfo appInfo : applicationList) {
+            if (appInfo.packageName.equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private int getTestUser() {
+        final Bundle testArguments = InstrumentationRegistry.getArguments();
+        if (testArguments.containsKey("testUser")) {
+            try {
+                return Integer.parseInt(testArguments.getString("testUser"));
+            } catch (NumberFormatException ignore) {}
+        }
+        return mContext.getUserId();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/Android.mk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/Android.mk
index feaaa03..9fd8b98 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/Android.mk
@@ -28,4 +28,12 @@
 LOCAL_SRC_FILES := b71361168.apk
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 LOCAL_CERTIFICATE := PRESIGNED
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CtsCorruptApkTests_b79488511
+LOCAL_MODULE_CLASS := APPS
+LOCAL_SRC_FILES := b79488511.apk
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_CERTIFICATE := PRESIGNED
 include $(BUILD_PREBUILT)
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/b71361168.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/b71361168.apk
index ef1e2bf..dc00656 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/b71361168.apk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/b71361168.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/b79488511.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/b79488511.apk
new file mode 100644
index 0000000..22af499
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/b79488511.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
index af75334..1d0f83e 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
@@ -173,6 +173,9 @@
         mDevice.pressMenu();
         mDevice.waitForIdle();
         enterTestPin();
+        mDevice.waitForIdle();
+        mDevice.pressHome();
+        mDevice.waitForIdle();
     }
 
     public void assertLocked() throws Exception {
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.mk b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.mk
index dab340b..90b7866 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.mk
@@ -22,8 +22,8 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     cts-aia-util \
     android-support-test \
-	ctsdeviceutillegacy \
-	ctstestrunner
+    ctsdeviceutillegacy \
+    ctstestrunner
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/AndroidManifest.xml
index c1f903e..2dc1b02 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/AndroidManifest.xml
@@ -36,7 +36,7 @@
         <uses-library android:name="android.test.runner" />
         <activity
             android:name=".EphemeralActivity"
-            android:theme="@android:style/Theme.NoDisplay">
+            android:theme="@android:style/Theme.NoDisplay" >
             <!-- TEST: normal app can start w/o knowing about this activity -->
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
@@ -67,6 +67,19 @@
                        android:name="android.app.searchable"
                        android:resource="@xml/searchable" />
         </activity>
+        <activity
+            android:name=".EphemeralResult"
+            android:theme="@android:style/Theme.NoDisplay" >
+            <!-- TEST: allow sending results from other instant apps -->
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="cts.google.com" />
+                <data android:path="/result" />
+            </intent-filter>
+        </activity>
         <provider android:name=".SearchSuggestionProvider"
             android:authorities="com.android.cts.ephemeralapp1.Search" />
 
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 363dfb0..9e231a1 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -21,6 +21,7 @@
 import static android.media.MediaRecorder.AudioSource.MIC;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertSame;
@@ -78,6 +79,7 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.SynchronousQueue;
@@ -97,6 +99,8 @@
     /** Action to start private ephemeral test activities */
     private static final String ACTION_START_EPHEMERAL_PRIVATE =
             "com.android.cts.ephemeraltest.START_EPHEMERAL_PRIVATE";
+    private static final String ACTION_START_EPHEMERAL_ACTIVITY =
+            "com.android.cts.ephemeraltest.START_OTHER_EPHEMERAL";
     /** Action to query for test activities */
     private static final String ACTION_QUERY =
             "com.android.cts.ephemeraltest.QUERY";
@@ -195,6 +199,52 @@
                     is(false));
         }
 
+        // query own ephemeral application activities with a web URI
+        {
+            final Intent queryIntent = new Intent(Intent.ACTION_VIEW);
+            queryIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+            queryIntent.setData(Uri.parse("https://cts.google.com/ephemeral"));
+            final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext()
+                    .getPackageManager().queryIntentActivities(
+                            queryIntent, PackageManager.GET_RESOLVED_FILTER);
+            if (resolveInfo == null || resolveInfo.size() == 0) {
+                fail("didn't resolve any intents");
+            }
+            for (ResolveInfo info: resolveInfo) {
+                assertThat(info.filter, is(notNullValue()));
+                if (handlesAllWebData(info.filter)) {
+                    continue;
+                }
+                assertThat(info.activityInfo.packageName,
+                        is("com.android.cts.ephemeralapp1"));
+                assertThat(info.activityInfo.name,
+                        is("com.android.cts.ephemeralapp1.EphemeralActivity"));
+                assertThat(info.isInstantAppAvailable,
+                        is(true));
+            }
+        }
+
+        // query other ephemeral application activities with a web URI
+        {
+            final Intent queryIntent = new Intent(Intent.ACTION_VIEW);
+            queryIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+            queryIntent.setData(Uri.parse("https://cts.google.com/other"));
+            final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext()
+                    .getPackageManager().queryIntentActivities(
+                            queryIntent, PackageManager.GET_RESOLVED_FILTER);
+            if (resolveInfo == null || resolveInfo.size() == 0) {
+                fail("didn't resolve any intents");
+            }
+            for (ResolveInfo info: resolveInfo) {
+                assertThat(info.filter, is(notNullValue()));
+                if (handlesAllWebData(info.filter)) {
+                    continue;
+                }
+                fail("resolution should have only matched browsers");
+            }
+        }
+
+        // query services
         {
             final Intent queryIntent = new Intent(ACTION_QUERY);
             final List<ResolveInfo> resolveInfo = InstrumentationRegistry
@@ -215,6 +265,7 @@
                     is(false));
         }
 
+        // query services; directed package
         {
             final Intent queryIntent = new Intent(ACTION_QUERY);
             queryIntent.setPackage("com.android.cts.ephemeralapp1");
@@ -230,6 +281,7 @@
                     is("com.android.cts.ephemeralapp1.EphemeralService"));
         }
 
+        // query services; directed component
         {
             final Intent queryIntent = new Intent(ACTION_QUERY);
             queryIntent.setComponent(
@@ -790,7 +842,7 @@
                     new ComponentName("com.android.cts.ephemeralapp1",
                             "com.android.cts.ephemeralapp1.EphemeralActivity3"));
             InstrumentationRegistry
-            .getContext().startActivity(startEphemeralIntent, null /*options*/);
+                    .getContext().startActivity(startEphemeralIntent, null /*options*/);
             final TestResult testResult = getResult();
             assertThat(testResult.getPackageName(),
                     is("com.android.cts.ephemeralapp1"));
@@ -802,6 +854,52 @@
                     is(nullValue()));
         }
 
+        // start an ephemeral activity; VIEW / BROWSABLE intent
+        {
+            final Intent startEphemeralIntent = new Intent(Intent.ACTION_VIEW)
+                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            startEphemeralIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+            startEphemeralIntent.setData(Uri.parse("https://cts.google.com/other"));
+            InstrumentationRegistry
+                    .getContext().startActivity(startEphemeralIntent, null /*options*/);
+            final TestResult testResult = getResult();
+            assertThat(testResult.getPackageName(),
+                    is("com.android.cts.ephemeralapp2"));
+            assertThat(testResult.getComponentName(),
+                    is("EphemeralActivity"));
+            assertThat(testResult.getIntent().getAction(),
+                    is(Intent.ACTION_VIEW));
+            assertThat(testResult.getIntent().getCategories(),
+                    hasItems(Intent.CATEGORY_BROWSABLE));
+            assertThat(testResult.getIntent().getData().toString(),
+                    is("https://cts.google.com/other"));
+            assertThat(testResult.getStatus(),
+                    is("PASS"));
+            assertThat(testResult.getException(),
+                    is(nullValue()));
+        }
+
+        // start an ephemeral activity; EXTERNAL flag
+        {
+            final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_ACTIVITY)
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
+            InstrumentationRegistry.getContext().startActivity(
+                    startEphemeralIntent, null /*options*/);
+            final TestResult testResult = getResult();
+            assertThat(testResult.getPackageName(),
+                    is("com.android.cts.ephemeralapp2"));
+            assertThat(testResult.getComponentName(),
+                    is("EphemeralActivity"));
+            assertThat(testResult.getIntent().getAction(),
+                    is(ACTION_START_EPHEMERAL_ACTIVITY));
+            assertThat(testResult.getIntent().getData(),
+                    is(nullValue()));
+            assertThat(testResult.getStatus(),
+                    is("PASS"));
+            assertThat(testResult.getException(),
+                    is(nullValue()));
+        }
+
         // start the ephemeral service; directed package
         {
             final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL);
@@ -1280,6 +1378,32 @@
         }
     }
 
+    /** Returns {@code true} if the given filter handles all web URLs, regardless of host. */
+    private boolean handlesAllWebData(IntentFilter filter) {
+        return filter.hasCategory(Intent.CATEGORY_APP_BROWSER) ||
+                (handlesWebUris(filter) && filter.countDataAuthorities() == 0);
+    }
+
+    /** Returns {@code true} if the given filter handles at least one web URL. */
+    private boolean handlesWebUris(IntentFilter filter) {
+        // Require ACTION_VIEW, CATEGORY_BROWSEABLE, and at least one scheme
+        if (!filter.hasAction(Intent.ACTION_VIEW)
+            || !filter.hasCategory(Intent.CATEGORY_BROWSABLE)
+            || filter.countDataSchemes() == 0) {
+            return false;
+        }
+        // Now allow only the schemes "http" and "https"
+        final Iterator<String> schemesIterator = filter.schemesIterator();
+        while (schemesIterator.hasNext()) {
+            final String scheme = schemesIterator.next();
+            final boolean isWebScheme = "http".equals(scheme) || "https".equals(scheme);
+            if (isWebScheme) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private TestResult getResult() {
         final TestResult result;
         try {
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/EphemeralResult.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/EphemeralResult.java
new file mode 100644
index 0000000..a1fad50
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/EphemeralResult.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.ephemeralapp1;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.SearchRecentSuggestions;
+import android.util.Log;
+
+import com.android.cts.util.TestResult;
+
+import java.util.List;
+
+public class EphemeralResult extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final Intent intent  = getIntent();
+        if (Intent.ACTION_VIEW.equals(intent.getAction())
+                && intent.hasExtra(TestResult.EXTRA_TEST_RESULT)) {
+            ((TestResult) intent.getParcelableExtra(TestResult.EXTRA_TEST_RESULT)).broadcast(this);
+        }
+        finish();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.mk b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.mk
index a5bc4b0..78c7970 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.mk
@@ -17,12 +17,18 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
 LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    cts-aia-util \
+    android-support-test \
+    ctsdeviceutillegacy \
+    ctstestrunner
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := CtsEphemeralTestsEphemeralApp2
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/AndroidManifest.xml
index 84549b0..0350cc6 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/AndroidManifest.xml
@@ -43,6 +43,10 @@
                 <action android:name="com.android.cts.ephemeraltest.START_EPHEMERAL" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
+            <intent-filter android:priority="0">
+                <action android:name="com.android.cts.ephemeraltest.START_OTHER_EPHEMERAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.SEARCH" />
             </intent-filter>
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralActivity.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralActivity.java
new file mode 100644
index 0000000..885bc19
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.ephemeralapp2;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.SearchRecentSuggestions;
+import android.util.Log;
+
+import com.android.cts.util.TestResult;
+
+import java.util.List;
+
+public class EphemeralActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final Intent intent  = getIntent();
+        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
+            final String query = intent.getStringExtra(SearchManager.QUERY);
+            final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
+                    SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
+            suggestions.saveRecentQuery(query, null);
+        }
+
+        TestResult.getBuilder()
+                .setPackageName("com.android.cts.ephemeralapp2")
+                .setComponentName("EphemeralActivity")
+                .setIntent(getIntent())
+                .setStatus("PASS")
+                .build()
+                .startActivity(this, Uri.parse("https://cts.google.com/result"));
+        finish();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralProvider.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralProvider.java
new file mode 100644
index 0000000..a0664fe
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/src/com/android/cts/ephemeralapp2/EphemeralProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.ephemeralapp2;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.CharArrayBuffer;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Bundle;
+
+public class EphemeralProvider extends ContentProvider {
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+    static {
+        sUriMatcher.addURI("com.android.cts.ephemeralapp2.provider", "table", 1);
+    }
+    private static final String[] sColumnNames = { "_ID", "name" };
+    private static final MatrixCursor sCursor = new MatrixCursor(sColumnNames, 1);
+    static {
+        sCursor.newRow().add(1).add("InstantAppProvider");
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return (sUriMatcher.match(uri) != 1) ? null : sCursor;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+}
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/util/src/com/android/cts/util/TestResult.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/util/src/com/android/cts/util/TestResult.java
index 0f52e80..632ded9 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/util/src/com/android/cts/util/TestResult.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/util/src/com/android/cts/util/TestResult.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -75,6 +76,14 @@
         context.sendBroadcast(broadcastIntent);
     }
 
+    public void startActivity(Context context, Uri uri) {
+        final Intent broadcastIntent = new Intent(Intent.ACTION_VIEW);
+        broadcastIntent.addCategory(Intent.CATEGORY_BROWSABLE);
+        broadcastIntent.putExtra(EXTRA_TEST_RESULT, this);
+        broadcastIntent.setData(uri);
+        context.startActivity(broadcastIntent);
+    }
+
     private TestResult(String packageName, String componentName, String methodName,
             String status, String exception, Intent intent,
             boolean ephemeralPackageInfoExposed) {
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/Android.mk b/hostsidetests/appsecurity/test-apps/NoRestartApp/Android.mk
index 23db742..656f54a 100644
--- a/hostsidetests/appsecurity/test-apps/NoRestartApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/Android.mk
@@ -20,15 +20,19 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
 LOCAL_PACKAGE_NAME := CtsNoRestartBase
 LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+LOCAL_SDK_VERSION := test_current
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/NoRestartApp/AndroidManifest.xml
index 7140333..a8aa042 100644
--- a/hostsidetests/appsecurity/test-apps/NoRestartApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/AndroidManifest.xml
@@ -16,20 +16,21 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.cts.norestart"
+    android:targetSandboxVersion="2"
     tools:ignore="MissingVersion" >
 
-    <uses-sdk
-        android:minSdkVersion="8"
-        android:targetSdkVersion="23" />
-
     <application
         tools:ignore="AllowBackup,MissingApplicationIcon" >
         <activity
             android:name=".NoRestartActivity"
-            android:launchMode="singleTop" >
+            android:launchMode="singleTop">
             <intent-filter>
-                <action android:name="com.android.cts.norestart.START" />
+                <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="foo.com" />
+                <data android:path="/bar" />
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -37,4 +38,8 @@
             </intent-filter>
             </activity>
     </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+             android:targetPackage="com.android.cts.norestart" />
+
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/Android.mk
index 08fa1bd..3558eb7 100644
--- a/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/AndroidManifest.xml
index b2fa3e8..f98cb0d 100644
--- a/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/feature/AndroidManifest.xml
@@ -16,13 +16,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.cts.norestart"
+    android:targetSandboxVersion="2"
     split="feature"
     tools:ignore="MissingVersion" >
 
-    <uses-sdk
-        android:minSdkVersion="8"
-        android:targetSdkVersion="23" />
-
     <application
         android:allowBackup="false"
         tools:ignore="MissingApplicationIcon" >
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartActivity.java b/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartActivity.java
index 26d5712..09ea8bd 100644
--- a/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartActivity.java
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartActivity.java
@@ -16,35 +16,38 @@
 
 package com.android.cts.norestart;
 
+import android.content.Intent;
+import android.os.RemoteCallback;
 import com.android.cts.norestart.R;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.os.Bundle;
 
 public class NoRestartActivity extends Activity {
-    private int mCreateCount;
+    private static int sCreateCount;
     private int mNewIntentCount;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.no_restart_activity);
-        mCreateCount++;
-        sendBroadcast();
+        sCreateCount++;
+        final RemoteCallback callback = getIntent().getParcelableExtra("RESPONSE");
+        sendResponse(callback);
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
         mNewIntentCount++;
-        sendBroadcast();
+        final RemoteCallback callback = intent.getParcelableExtra("RESPONSE");
+        sendResponse(callback);
     }
 
-    private void sendBroadcast() {
-        final Intent intent = new Intent("com.android.cts.norestart.BROADCAST");
-        intent.putExtra("CREATE_COUNT", mCreateCount);
-        intent.putExtra("NEW_INTENT_COUNT", mNewIntentCount);
-        sendBroadcast(intent);
+    private void sendResponse(RemoteCallback callback) {
+        final Bundle payload = new Bundle();
+        payload.putInt("CREATE_COUNT", sCreateCount);
+        payload.putInt("NEW_INTENT_COUNT", mNewIntentCount);
+        callback.sendResult(payload);
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartTest.java b/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartTest.java
new file mode 100644
index 0000000..7c9dc2c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/NoRestartApp/src/com/android/cts/norestart/NoRestartTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.norestart;
+
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class NoRestartTest {
+    @Test
+    public void testPokeFullApp() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.cts.splitapp", "com.android.cts.splitapp.MyActivity");
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        InstrumentationRegistry.getContext().startActivity(intent);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
index a0a8080..c63bcb6 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_PACKAGE_SPLITS := mdpi-v4 hdpi-v4 xhdpi-v4 xxhdpi-v4 v7 fr de
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
 
@@ -40,6 +40,8 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+LOCAL_SDK_VERSION := test_current
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
@@ -60,7 +62,7 @@
 LOCAL_PACKAGE_SPLITS := v7
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MANIFEST_FILE := revision/AndroidManifest.xml
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
@@ -69,6 +71,8 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+LOCAL_SDK_VERSION := test_current
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
@@ -89,7 +93,7 @@
 LOCAL_PACKAGE_SPLITS := v7
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 101 --version-name OneHundredOne --replace-version
@@ -97,6 +101,8 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+LOCAL_SDK_VERSION := test_current
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
@@ -117,7 +123,7 @@
 LOCAL_PACKAGE_SPLITS := v7
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version
@@ -125,6 +131,8 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
+LOCAL_SDK_VERSION := test_current
+
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
index e9e3625..f56398e 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
@@ -15,7 +15,9 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.splitapp">
+    package="com.android.cts.splitapp"
+    android:targetSandboxVersion="2">
+
     <!-- TODO(b/73365611) Remove targetSdkVersion once EncryptionApp tests
          are fixed to no longer access SplitApp's data by path. -->
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
@@ -24,7 +26,7 @@
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
     <application android:label="SplitApp">
-        <activity android:name=".MyActivity">
+        <activity android:name=".MyActivity" android:visibleToInstantApps="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
index 06901d8..46abb3c 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 featureOf := CtsSplitApp
 featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
index 5337057..e2e059c 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
index 7fceede..ff827b9 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
index 9149930..29bc859 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
index 95d02d0..3c6cc22 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
index ad10be0..acb545f 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
index f008564..8f3b381 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
index ded5b29..76ef050 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := raw
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/revision/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/revision/AndroidManifest.xml
index 8e053ba..a17d470 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/revision/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/revision/AndroidManifest.xml
@@ -16,7 +16,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.cts.splitapp"
-        android:revisionCode="12">
+        android:revisionCode="12"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.CAMERA" />
 
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java
index 9b9f01c..cc875bd 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/MyActivity.java
@@ -17,6 +17,12 @@
 package com.android.cts.splitapp;
 
 import android.app.Activity;
+import android.os.Bundle;
 
 public class MyActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        finish();
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
index 4cfd7d0..3288aca 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
@@ -19,10 +19,8 @@
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -35,12 +33,12 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.os.StatFs;
+import android.os.RemoteCallback;
 import android.system.Os;
-import android.system.OsConstants;
 import android.system.StructStat;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
@@ -54,7 +52,6 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -309,23 +306,7 @@
     }
 
     public void testBaseInstalled() throws Exception {
-        final ConditionVariable cv = new ConditionVariable();
-        final BroadcastReceiver r = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                assertEquals(1, intent.getIntExtra("CREATE_COUNT", -1));
-                assertEquals(0, intent.getIntExtra("NEW_INTENT_COUNT", -1));
-                cv.open();
-            }
-        };
-        final IntentFilter filter = new IntentFilter("com.android.cts.norestart.BROADCAST");
-        getContext().registerReceiver(r, filter);
-        final Intent i = new Intent("com.android.cts.norestart.START");
-        i.addCategory(Intent.CATEGORY_DEFAULT);
-        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(i);
-        assertTrue(cv.block(2000L));
-        getContext().unregisterReceiver(r);
+        launchBaseActivity(1, 0);
     }
 
     /**
@@ -335,23 +316,27 @@
      * done in {@link #testBaseInstalled()}.
      */
     public void testFeatureInstalled() throws Exception {
+        launchBaseActivity(1, 1);
+    }
+
+    private void launchBaseActivity(int expectedCreateCount, int expectedNewIntentCount) {
         final ConditionVariable cv = new ConditionVariable();
-        final BroadcastReceiver r = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                assertEquals(1, intent.getIntExtra("CREATE_COUNT", -1));
-                assertEquals(1, intent.getIntExtra("NEW_INTENT_COUNT", -1));
-                cv.open();
-            }
-        };
-        final IntentFilter filter = new IntentFilter("com.android.cts.norestart.BROADCAST");
-        getContext().registerReceiver(r, filter);
-        final Intent i = new Intent("com.android.cts.norestart.START");
+
+        final Intent i = new Intent(Intent.ACTION_VIEW);
+        i.setPackage("com.android.cts.norestart");
         i.addCategory(Intent.CATEGORY_DEFAULT);
+        i.addCategory(Intent.CATEGORY_BROWSABLE);
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        i.setData(Uri.parse("https://foo.com/bar"));
+
+        i.putExtra("RESPONSE", new RemoteCallback((Bundle result) -> {
+            assertEquals(expectedCreateCount, result.getInt("CREATE_COUNT", -1));
+            assertEquals(expectedNewIntentCount, result.getInt("NEW_INTENT_COUNT", -1));
+            cv.open();
+        }));
+
         getContext().startActivity(i);
         assertTrue(cv.block(2000L));
-        getContext().unregisterReceiver(r);
     }
 
     public void testFeatureApi() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 212cb01..3cb0bce 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -185,6 +185,12 @@
           </intent-filter>
         </receiver>
 
+        <receiver android:name=".LockProfileReceiver">
+          <intent-filter>
+            <action android:name="com.android.cts.managedprofile.LOCK_PROFILE" />
+          </intent-filter>
+        </receiver>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockNowTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockNowTest.java
deleted file mode 100644
index fd5fcd2..0000000
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockNowTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.managedprofile;
-
-import android.app.admin.DevicePolicyManager;
-
-/**
- * Test lockNow() for use in a managed profile. If called from a managed profile. lockNow() can be
- * passed a flag to evict the CE key of the profile.
- */
-public class LockNowTest extends BaseManagedProfileTest {
-
-  public void testLockNowWithKeyEviction() throws InterruptedException {
-        mDevicePolicyManager.lockNow(DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY);
-        // The test that the managed profile was locked is done in the host
-    }
-
-}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockProfileReceiver.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockProfileReceiver.java
new file mode 100644
index 0000000..59f13e1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/LockProfileReceiver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.managedprofile;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Invoke lockNow() with a flag to evict the CE key of the profile. Used by the hostside test to
+ * lock the profile with key eviction. This is triggered via a broadcast instead of a normal
+ * test case, since the test process will be killed after calling lockNow() which will result in
+ * a test failure if this were run as a test case.
+ */
+public class LockProfileReceiver extends BroadcastReceiver {
+
+    private static final String ACTION_LOCK_PROFILE = "com.android.cts.managedprofile.LOCK_PROFILE";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (ACTION_LOCK_PROFILE.equals(intent.getAction())) {
+            final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+            dpm.lockNow(DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ResetPasswordWithTokenTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ResetPasswordWithTokenTest.java
index 6487b50..4ea8f3b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ResetPasswordWithTokenTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ResetPasswordWithTokenTest.java
@@ -40,12 +40,11 @@
     }
 
     /**
-     * Set a reset password token and work challenge on the work profile, and then lock it
-     * with CE evicted. This is the preparation step for {@link #testResetPasswordBeforeUnlock}
-     * to put the profile in RUNNING_LOCKED state, and will be called by the hostside logic before
-     * {@link #testResetPasswordBeforeUnlock} is exercised.
+     * Set a reset password token and work challenge on the work profile. This is the preparation
+     * step for {@link #testResetPasswordBeforeUnlock} and will be called by the hostside logic
+     * before it is exercised.
      */
-    public void testSetupWorkProfileAndLock() {
+    public void testSetupWorkProfile() {
         testSetResetPasswordToken();
         // Reset password on the work profile will enable separate work challenge for it.
         assertTrue(mDevicePolicyManager.resetPasswordWithToken(ADMIN_RECEIVER_COMPONENT, PASSWORD0,
@@ -54,8 +53,6 @@
         mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT,
                 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
         mDevicePolicyManager.setPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT, 6);
-
-        testLockWorkProfile();
     }
 
     public void testResetPasswordBeforeUnlock() {
@@ -74,8 +71,4 @@
         assertTrue(mDevicePolicyManager.setResetPasswordToken(ADMIN_RECEIVER_COMPONENT, token));
         assertTrue(mDevicePolicyManager.isResetPasswordTokenActive(ADMIN_RECEIVER_COMPONENT));
     }
-
-    public void testLockWorkProfile() {
-        mDevicePolicyManager.lockNow(DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY);
-    }
 }
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index b67ce81..2dd5a2a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -199,8 +199,14 @@
             return;
         }
         changeUserCredential("1234", null, mProfileUserId);
-        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".LockNowTest",
-                "testLockNowWithKeyEviction", mProfileUserId);
+        lockProfile();
+    }
+
+    private void lockProfile() throws Exception {
+        final String cmd = "am broadcast --receiver-foreground --user " + mProfileUserId
+                + " -a com.android.cts.managedprofile.LOCK_PROFILE"
+                + " com.android.cts.managedprofile/.LockProfileReceiver";
+        getDevice().executeShellCommand(cmd);
         waitUntilProfileLocked();
     }
 
@@ -1152,8 +1158,8 @@
         }
 
         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
-                "testSetupWorkProfileAndLock", mProfileUserId);
-        waitUntilProfileLocked();
+                "testSetupWorkProfile", mProfileUserId);
+        lockProfile();
         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                 "testResetPasswordBeforeUnlock", mProfileUserId);
         // Password needs to be in sync with ResetPasswordWithTokenTest.PASSWORD1
@@ -1179,10 +1185,7 @@
             changeUserCredential(devicePassword, null, mParentUserId);
             changeUserCredential(null, devicePassword, mParentUserId);
             changeUserCredential(devicePassword, null, mParentUserId);
-
-            runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
-                    "testLockWorkProfile", mProfileUserId);
-            waitUntilProfileLocked();
+            lockProfile();
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ResetPasswordWithTokenTest",
                     "testResetPasswordBeforeUnlock", mProfileUserId);
             verifyUserCredential(RESET_PASSWORD_TEST_DEFAULT_PASSWORD, mProfileUserId);
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.apk
new file mode 100644
index 0000000..6760973
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.dm
index 1c02dff..754b4fd 100644
--- a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.dm
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitApp.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.apk
new file mode 100644
index 0000000..875feb5
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.dm
index 24b9ed9..18395f4 100644
--- a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.dm
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureA.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/BaseInstallMultiple.java b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/BaseInstallMultiple.java
index ad41c74..eb9498e 100644
--- a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/BaseInstallMultiple.java
+++ b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/BaseInstallMultiple.java
@@ -52,13 +52,12 @@
         return (T) this;
     }
 
-    T addApk(String apk) throws FileNotFoundException {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
-        mFilesToInstall.add(buildHelper.getTestFile(apk));
+    T addApk(File apk) {
+        mFilesToInstall.add(apk);
         return (T) this;
     }
 
-    T addDm(File dma) throws FileNotFoundException {
+    T addDm(File dma) {
         mFilesToInstall.add(dma);
         return (T) this;
     }
diff --git a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
index d0299af..766034a 100644
--- a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
+++ b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
@@ -61,6 +61,8 @@
     private static final String DM_FEATURE_A = "CtsDexMetadataSplitAppFeatureA.dm";
 
     private File mTmpDir;
+    private File mApkBaseFile = null;
+    private File mApkFeatureAFile = null;
     private File mDmBaseFile = null;
     private File mDmFeatureAFile = null;
     private boolean mShouldRunTests;
@@ -79,6 +81,8 @@
 
         if (mShouldRunTests) {
             mTmpDir = FileUtil.createTempDir("InstallDexMetadataHostTest");
+            mApkBaseFile = extractResource(APK_BASE, mTmpDir);
+            mApkFeatureAFile = extractResource(APK_FEATURE_A, mTmpDir);
             mDmBaseFile = extractResource(DM_BASE, mTmpDir);
             mDmFeatureAFile = extractResource(DM_FEATURE_A, mTmpDir);
         }
@@ -98,7 +102,7 @@
      */
     @Test
     public void testInstallDmForBase() throws Exception {
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBase"));
@@ -109,8 +113,8 @@
      */
     @Test
     public void testInstallDmForBaseAndSplit() throws Exception {
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile)
-                .addApk(APK_FEATURE_A).addDm(mDmFeatureAFile).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile)
+                .addApk(mApkFeatureAFile).addDm(mDmFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseAndSplit"));
@@ -121,8 +125,8 @@
      */
     @Test
     public void testInstallDmForBaseButNoSplit() throws Exception {
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile)
-                .addApk(APK_FEATURE_A).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile)
+                .addApk(mApkFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseButNoSplit"));
@@ -133,8 +137,8 @@
      */
     @Test
     public void testInstallDmForSplitButNoBase() throws Exception {
-        new InstallMultiple().addApk(APK_BASE)
-                .addApk(APK_FEATURE_A).addDm(mDmFeatureAFile).run();
+        new InstallMultiple().addApk(mApkBaseFile)
+                .addApk(mApkFeatureAFile).addDm(mDmFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForSplitButNoBase"));
@@ -145,22 +149,22 @@
      */
     @Test
     public void testUpdateDm() throws Exception {
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile)
-                .addApk(APK_FEATURE_A).addDm(mDmFeatureAFile).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile)
+                .addApk(mApkFeatureAFile).addDm(mDmFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseAndSplit"));
 
         // Remove .dm files during update.
-        new InstallMultiple().addArg("-r").addApk(APK_BASE)
-                .addApk(APK_FEATURE_A).run();
+        new InstallMultiple().addArg("-r").addApk(mApkBaseFile)
+                .addApk(mApkFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testNoDm"));
 
         // Add only a split .dm file during update.
-        new InstallMultiple().addArg("-r").addApk(APK_BASE)
-                .addApk(APK_FEATURE_A).addDm(mDmFeatureAFile).run();
+        new InstallMultiple().addArg("-r").addApk(mApkBaseFile)
+                .addApk(mApkFeatureAFile).addDm(mDmFeatureAFile).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForSplitButNoBase"));
@@ -174,8 +178,8 @@
         File nonMatchingDm = new File(mDmFeatureAFile.getAbsoluteFile().getAbsolutePath()
                 .replace(".dm", ".not.there.dm"));
         FileUtil.copyFile(mDmFeatureAFile, nonMatchingDm);
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile)
-                .addApk(APK_FEATURE_A).addDm(nonMatchingDm).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile)
+                .addApk(mApkFeatureAFile).addDm(nonMatchingDm).run();
         assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
 
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseButNoSplit"));
@@ -186,7 +190,7 @@
         assumeProfilesAreEnabled();
 
         // Install the app.
-        new InstallMultiple().addApk(APK_BASE).addDm(mDmBaseFile).run();
+        new InstallMultiple().addApk(mApkBaseFile).addDm(mDmBaseFile).run();
 
         // Take a snapshot of the installed profile.
         String snapshotCmd = "cmd package snapshot-profile " + INSTALL_PACKAGE;
@@ -197,9 +201,6 @@
         byte[] snapshotProfileBytes = extractProfileSnapshotFromDevice();
         byte[] expectedProfileBytes = extractProfileFromDexMetadata(mDmBaseFile);
 
-        // Clean up the snapshot profile.
-        getDevice().executeShellCommand("rm " + INSTALL_PACKAGE + ".prof");
-
         assertArrayEquals(expectedProfileBytes, snapshotProfileBytes);
     }
 
@@ -215,10 +216,14 @@
     private byte[] extractProfileSnapshotFromDevice() throws Exception {
         File snapshotFile = File.createTempFile(INSTALL_PACKAGE, "primary.prof");
         snapshotFile.deleteOnExit();
-        getDevice().pullFile("/data/misc/profman/" + INSTALL_PACKAGE + ".prof", snapshotFile);
+        getDevice().pullFile(getSnapshotLocation(INSTALL_PACKAGE), snapshotFile);
         return Files.readAllBytes(snapshotFile.toPath());
     }
 
+    static private String getSnapshotLocation(String pkg) {
+        return "/data/misc/profman/" + pkg + ".prof";
+    }
+
     /** Extracts the profile bytes from the dex metadata profile. */
     static private byte[] extractProfileFromDexMetadata(File dmFile) throws Exception {
         try (ZipInputStream in = new ZipInputStream(new FileInputStream(dmFile))) {
diff --git a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
index 20a6cab..2747972 100644
--- a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
@@ -60,7 +60,10 @@
         assertTrue(0 <= dump.getUsedPssKb());
         assertTrue(0 <= dump.getUsedKernelKb());
 
-        assertTrue(0 <= dump.getLostRamKb());
+        // Ideally lost RAM would not be negative, but there's an issue where it's sometimes
+        // calculated to be negative.
+        // TODO: re-enable check once the underlying bug has been fixed.
+        // assertTrue(0 <= dump.getLostRamKb());
 
         assertTrue(0 <= dump.getTotalZramKb());
         assertTrue(0 <= dump.getZramPhysicalUsedInSwapKb());
diff --git a/hostsidetests/inputmethodservice/common/Android.mk b/hostsidetests/inputmethodservice/common/Android.mk
index 8d03e93..94b59c9 100644
--- a/hostsidetests/inputmethodservice/common/Android.mk
+++ b/hostsidetests/inputmethodservice/common/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MODULE := CtsInputMethodServiceCommon
 
diff --git a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/EditTextAppConstants.java b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/EditTextAppConstants.java
index f575c55..9f6d4d1 100644
--- a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/EditTextAppConstants.java
+++ b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/EditTextAppConstants.java
@@ -22,4 +22,7 @@
     public static final String PACKAGE = "android.inputmethodservice.cts.edittextapp";
     public static final String CLASS =   PACKAGE + ".MainActivity";
     public static final String APK = "EditTextApp.apk";
+    public static final String EDIT_TEXT_RES_NAME = PACKAGE + ":id/edit_text_entry";
+    public static final String URI =
+            "https://example.com/android/inputmethodservice/cts/edittextapp";
 }
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/Android.mk b/hostsidetests/inputmethodservice/deviceside/devicetest/Android.mk
index 6f3a29d..1727ad7 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/Android.mk
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/Android.mk
@@ -36,7 +36,7 @@
     CtsInputMethodServiceLib
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsInputMethodServiceDeviceTests
 
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/AndroidManifest.xml b/hostsidetests/inputmethodservice/deviceside/devicetest/AndroidManifest.xml
index 5566613..e585bcb 100755
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/AndroidManifest.xml
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/AndroidManifest.xml
@@ -30,16 +30,6 @@
         android:allowBackup="false"
     >
         <uses-library android:name="android.test.runner" />
-
-        <activity
-            android:name=".InputMethodServiceTestActivity"
-            android:label="InputMethodSercuceTestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
     </application>
 
     <instrumentation
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/res/layout/activity_inputmethod_test.xml b/hostsidetests/inputmethodservice/deviceside/devicetest/res/layout/activity_inputmethod_test.xml
deleted file mode 100644
index 94ba557..0000000
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/res/layout/activity_inputmethod_test.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2017 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:padding="10px">
-
-    <EditText
-        android:id="@+id/text_entry"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:background="@android:drawable/editbox_background"/>
-
-</RelativeLayout>
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
index 1250d35..47ae8eb 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
@@ -71,7 +71,8 @@
         final TestHelper helper = new TestHelper(getClass(), DeviceTestConstants.TEST_CREATE_IME1);
 
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
 
         pollingCheck(() -> helper.queryAllEvents()
                         .collect(startingFrom(helper.isStartOfTest()))
@@ -90,7 +91,8 @@
                 getClass(), DeviceTestConstants.TEST_SWITCH_IME1_TO_IME2);
 
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
 
         pollingCheck(() -> helper.queryAllEvents()
                         .collect(startingFrom(helper.isStartOfTest()))
@@ -101,7 +103,7 @@
                         .anyMatch(isFrom(Ime1Constants.CLASS).and(isType(ON_START_INPUT))),
                 TIMEOUT, "CtsInputMethod1.onStartInput is called");
 
-        helper.findUiObject(R.id.text_entry).click();
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         // Switch IME from CtsInputMethod1 to CtsInputMethod2.
         final long switchImeTime = SystemClock.uptimeMillis();
@@ -132,12 +134,13 @@
         final TestHelper helper = new TestHelper(
                 getClass(), DeviceTestConstants.TEST_SWITCH_INPUTMETHOD);
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
         pollingCheck(() -> helper.queryAllEvents()
                         .filter(isNewerThan(startActivityTime))
                         .anyMatch(isFrom(Ime1Constants.CLASS).and(isType(ON_START_INPUT))),
                 TIMEOUT, "CtsInputMethod1.onStartInput is called");
-        helper.findUiObject(R.id.text_entry).click();
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         final long setImeTime = SystemClock.uptimeMillis();
         // call setInputMethodAndSubtype(IME2, null)
@@ -159,12 +162,13 @@
         final TestHelper helper = new TestHelper(
                 getClass(), DeviceTestConstants.TEST_SWITCH_NEXT_INPUT);
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
         pollingCheck(() -> helper.queryAllEvents()
                         .filter(isNewerThan(startActivityTime))
                         .anyMatch(isFrom(Ime1Constants.CLASS).and(isType(ON_START_INPUT))),
                 TIMEOUT, "CtsInputMethod1.onStartInput is called");
-        helper.findUiObject(R.id.text_entry).click();
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         pollingCheck(() -> helper.shell(ShellCommandUtils.getCurrentIme())
                         .equals(Ime1Constants.IME_ID),
@@ -182,8 +186,9 @@
         final TestHelper helper = new TestHelper(
                 getClass(), DeviceTestConstants.TEST_SWITCH_PREVIOUS_INPUT);
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
-        helper.findUiObject(R.id.text_entry).click();
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         final String initialIme = helper.shell(ShellCommandUtils.getCurrentIme());
         helper.shell(ShellCommandUtils.setCurrentIme(Ime2Constants.IME_ID));
@@ -204,8 +209,9 @@
         final TestHelper helper = new TestHelper(
                 getClass(), DeviceTestConstants.TEST_INPUT_UNBINDS_ON_IME_STOPPED);
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_ACTIVITY_CLASS);
-        helper.findUiObject(R.id.text_entry).click();
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         pollingCheck(() -> helper.queryAllEvents()
                         .filter(isNewerThan(startActivityTime))
@@ -220,7 +226,7 @@
         helper.shell(ShellCommandUtils.uninstallPackage(Ime1Constants.PACKAGE));
 
         helper.shell(ShellCommandUtils.setCurrentIme(Ime2Constants.IME_ID));
-        helper.findUiObject(R.id.text_entry).click();
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
         pollingCheck(() -> helper.queryAllEvents()
                         .filter(isNewerThan(imeForceStopTime))
                         .anyMatch(isFrom(Ime2Constants.CLASS).and(isType(ON_START_INPUT))),
@@ -236,7 +242,9 @@
         final TestHelper helper = new TestHelper(
                 getClass(), DeviceTestConstants.TEST_INPUT_UNBINDS_ON_APP_STOPPED);
         final long startActivityTime = SystemClock.uptimeMillis();
-        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS);
+        helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
+                EditTextAppConstants.URI);
+        helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
 
         pollingCheck(() -> helper.queryAllEvents()
                         .filter(isNewerThan(startActivityTime))
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceTestActivity.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceTestActivity.java
deleted file mode 100644
index 613c266..0000000
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceTestActivity.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.inputmethodservice.cts.devicetest;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class InputMethodServiceTestActivity extends Activity {
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_inputmethod_test);
-    }
-}
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/TestHelper.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/TestHelper.java
index 215ad0e..dda48a0 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/TestHelper.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/TestHelper.java
@@ -83,10 +83,14 @@
      * Launching an Activity for test, and wait for completions of launch.
      * @param packageName activity's app package name.
      * @param className activity's class name.
+     * @param uri uri to be handled.
      */
-    void launchActivity(final String packageName, final String className) {
+    void launchActivity(final String packageName, final String className, final String uri) {
         final Intent intent = new Intent()
-                .setAction(Intent.ACTION_MAIN)
+                .setAction(Intent.ACTION_VIEW)
+                .addCategory(Intent.CATEGORY_BROWSABLE)
+                .addCategory(Intent.CATEGORY_DEFAULT)
+                .setData(Uri.parse(uri))
                 .setClassName(packageName, className)
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
@@ -96,11 +100,10 @@
 
     /**
      * Find an UI element from resource ID.
-     * @param resId id of finding UI element.
+     * @param resourceName name of finding UI element.
      * @return {@link UiObject2} of found UI element.
      */
-    UiObject2 findUiObject(@IdRes int resId) {
-        final String resourceName = mTargetContext.getResources().getResourceName(resId);
+    UiObject2 findUiObject(String resourceName) {
         return mUiDevice.findObject(By.res(resourceName));
     }
 
diff --git a/hostsidetests/inputmethodservice/deviceside/edittextapp/Android.mk b/hostsidetests/inputmethodservice/deviceside/edittextapp/Android.mk
index 3461dbb..30fdb08 100644
--- a/hostsidetests/inputmethodservice/deviceside/edittextapp/Android.mk
+++ b/hostsidetests/inputmethodservice/deviceside/edittextapp/Android.mk
@@ -31,7 +31,7 @@
     CtsInputMethodServiceCommon
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := EditTextApp
 
diff --git a/hostsidetests/inputmethodservice/deviceside/edittextapp/AndroidManifest.xml b/hostsidetests/inputmethodservice/deviceside/edittextapp/AndroidManifest.xml
index e88ec8e..7565023 100755
--- a/hostsidetests/inputmethodservice/deviceside/edittextapp/AndroidManifest.xml
+++ b/hostsidetests/inputmethodservice/deviceside/edittextapp/AndroidManifest.xml
@@ -16,7 +16,10 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.inputmethodservice.cts.edittextapp">
+    package="android.inputmethodservice.cts.edittextapp" android:targetSandboxVersion="2">
+
+    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
+
     <application
         android:label="@string/app_name">
         <activity
@@ -26,6 +29,14 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="example.com" />
+                <data android:path="/android/inputmethodservice/cts/edittextapp" />
+            </intent-filter>
         </activity>
     </application>
 
diff --git a/hostsidetests/inputmethodservice/deviceside/ime1/Android.mk b/hostsidetests/inputmethodservice/deviceside/ime1/Android.mk
index f6da1c4..850b89f 100644
--- a/hostsidetests/inputmethodservice/deviceside/ime1/Android.mk
+++ b/hostsidetests/inputmethodservice/deviceside/ime1/Android.mk
@@ -32,7 +32,7 @@
     CtsInputMethodServiceLib
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsInputMethod1
 
diff --git a/hostsidetests/inputmethodservice/deviceside/ime2/Android.mk b/hostsidetests/inputmethodservice/deviceside/ime2/Android.mk
index e11e28a..fcd146c 100644
--- a/hostsidetests/inputmethodservice/deviceside/ime2/Android.mk
+++ b/hostsidetests/inputmethodservice/deviceside/ime2/Android.mk
@@ -32,7 +32,7 @@
     CtsInputMethodServiceLib
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsInputMethod2
 
diff --git a/hostsidetests/inputmethodservice/deviceside/provider/Android.mk b/hostsidetests/inputmethodservice/deviceside/provider/Android.mk
index 91f6ce7..b8f308d 100644
--- a/hostsidetests/inputmethodservice/deviceside/provider/Android.mk
+++ b/hostsidetests/inputmethodservice/deviceside/provider/Android.mk
@@ -31,7 +31,7 @@
     CtsInputMethodServiceLib
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsInputMethodServiceEventProvider
 
diff --git a/hostsidetests/inputmethodservice/hostside/Android.mk b/hostsidetests/inputmethodservice/hostside/Android.mk
index 5ff22a2..2cfca0e 100644
--- a/hostsidetests/inputmethodservice/hostside/Android.mk
+++ b/hostsidetests/inputmethodservice/hostside/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MODULE := CtsInputMethodServiceHostTestCases
 
diff --git a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
index 25fe8b1..c1557e1 100644
--- a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
+++ b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
@@ -32,6 +32,8 @@
 import android.inputmethodservice.cts.common.test.DeviceTestConstants;
 import android.inputmethodservice.cts.common.test.ShellCommandUtils;
 import android.inputmethodservice.cts.common.test.TestInfo;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -63,11 +65,20 @@
         shell(ShellCommandUtils.resetImes());
     }
 
-    @Test
-    public void testSwitchIme() throws Exception {
+    private void installPossibleInstantPackage(String apkFileName, boolean instant)
+            throws Exception {
+        if (instant) {
+            installPackage(apkFileName, "-r", "--instant");
+        } else {
+            installPackage(apkFileName, "-r");
+        }
+    }
+
+    private void testSwitchIme(boolean instant) throws Exception {
         final TestInfo testSwitchIme1ToIme2 = new TestInfo(DeviceTestConstants.PACKAGE,
                 DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_SWITCH_IME1_TO_IME2);
         sendTestStartEvent(testSwitchIme1ToIme2);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         installPackage(Ime2Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
@@ -77,11 +88,23 @@
         assertTrue(runDeviceTestMethod(testSwitchIme1ToIme2));
     }
 
+    @AppModeFull
     @Test
-    public void testUninstallCurrentIme() throws Exception {
+    public void testSwitchImeull() throws Exception {
+        testSwitchIme(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testSwitchImeInstant() throws Exception {
+        testSwitchIme(true);
+    }
+
+    private void testUninstallCurrentIme(boolean instant) throws Exception {
         final TestInfo testCreateIme1 = new TestInfo(DeviceTestConstants.PACKAGE,
                 DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_CREATE_IME1);
         sendTestStartEvent(testCreateIme1);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
         shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
@@ -91,11 +114,23 @@
         assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, TIMEOUT);
     }
 
+    @AppModeFull
     @Test
-    public void testDisableCurrentIme() throws Exception {
+    public void testUninstallCurrentImeFull() throws Exception {
+        testUninstallCurrentIme(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testUninstallCurrentImeInstant() throws Exception {
+        testUninstallCurrentIme(true);
+    }
+
+    private void testDisableCurrentIme(boolean instant) throws Exception {
         final TestInfo testCreateIme1 = new TestInfo(DeviceTestConstants.PACKAGE,
                 DeviceTestConstants.TEST_CLASS, DeviceTestConstants.TEST_CREATE_IME1);
         sendTestStartEvent(testCreateIme1);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
         shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
@@ -105,12 +140,24 @@
         assertImeNotSelectedInSecureSettings(Ime1Constants.IME_ID, TIMEOUT);
     }
 
+    @AppModeFull
     @Test
-    public void testSwitchInputMethod() throws Exception {
+    public void testDisableCurrentImeFull() throws Exception {
+        testDisableCurrentIme(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testDisableCurrentImeInstant() throws Exception {
+        testDisableCurrentIme(true);
+    }
+
+    private void testSwitchInputMethod(boolean instant) throws Exception {
         final TestInfo testSetInputMethod = new TestInfo(
                 DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
                 DeviceTestConstants.TEST_SWITCH_INPUTMETHOD);
         sendTestStartEvent(testSetInputMethod);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         installPackage(Ime2Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
@@ -120,12 +167,24 @@
         assertTrue(runDeviceTestMethod(testSetInputMethod));
     }
 
+    @AppModeFull
     @Test
-    public void testSwitchToNextInput() throws Exception {
+    public void testSwitchInputMethodFull() throws Exception {
+        testSwitchInputMethod(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testSwitchInputMethodInstant() throws Exception {
+        testSwitchInputMethod(true);
+    }
+
+    private void testSwitchToNextInput(boolean instant) throws Exception {
         final TestInfo testSwitchInputs = new TestInfo(
                 DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
                 DeviceTestConstants.TEST_SWITCH_NEXT_INPUT);
         sendTestStartEvent(testSwitchInputs);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         installPackage(Ime2Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
@@ -137,12 +196,24 @@
         assertTrue(runDeviceTestMethod(testSwitchInputs));
     }
 
+    @AppModeFull
     @Test
-    public void testSwitchToPreviousInput() throws Exception {
+    public void testSwitchToNextInputFull() throws Exception {
+        testSwitchToNextInput(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testSwitchToNextInputInstant() throws Exception {
+        testSwitchToNextInput(true);
+    }
+
+    private void testSwitchToPreviousInput(boolean instant) throws Exception {
         final TestInfo testSwitchInputs = new TestInfo(
                 DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
                 DeviceTestConstants.TEST_SWITCH_PREVIOUS_INPUT);
         sendTestStartEvent(testSwitchInputs);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         installPackage(Ime2Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
@@ -152,12 +223,24 @@
         assertTrue(runDeviceTestMethod(testSwitchInputs));
     }
 
+    @AppModeFull
     @Test
-    public void testInputUnbindsOnImeStopped() throws Exception {
+    public void testSwitchToPreviousInputFull() throws Exception {
+        testSwitchToPreviousInput(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testSwitchToPreviousInputInstant() throws Exception {
+        testSwitchToPreviousInput(true);
+    }
+
+    private void testInputUnbindsOnImeStopped(boolean instant) throws Exception {
         final TestInfo testUnbind = new TestInfo(
                 DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
                 DeviceTestConstants.TEST_INPUT_UNBINDS_ON_IME_STOPPED);
         sendTestStartEvent(testUnbind);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
         installPackage(Ime2Constants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
@@ -167,20 +250,43 @@
         assertTrue(runDeviceTestMethod(testUnbind));
     }
 
+    @AppModeFull
     @Test
-    public void testInputUnbindsOnAppStop() throws Exception {
+    public void testInputUnbindsOnImeStoppedFull() throws Exception {
+        testInputUnbindsOnImeStopped(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testInputUnbindsOnImeStoppedInstant() throws Exception {
+        testInputUnbindsOnImeStopped(true);
+    }
+
+    private void testInputUnbindsOnAppStop(boolean instant) throws Exception {
         final TestInfo testUnbind = new TestInfo(
                 DeviceTestConstants.PACKAGE, DeviceTestConstants.TEST_CLASS,
                 DeviceTestConstants.TEST_INPUT_UNBINDS_ON_APP_STOPPED);
         sendTestStartEvent(testUnbind);
+        installPossibleInstantPackage(EditTextAppConstants.APK, instant);
         installPackage(Ime1Constants.APK, "-r");
-        installPackage(EditTextAppConstants.APK, "-r");
         shell(ShellCommandUtils.enableIme(Ime1Constants.IME_ID));
         shell(ShellCommandUtils.setCurrentIme(Ime1Constants.IME_ID));
 
         assertTrue(runDeviceTestMethod(testUnbind));
     }
 
+    @AppModeFull
+    @Test
+    public void testInputUnbindsOnAppStopFull() throws Exception {
+        testInputUnbindsOnAppStop(false);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testInputUnbindsOnAppStopInstant() throws Exception {
+        testInputUnbindsOnAppStop(true);
+    }
+
     private void sendTestStartEvent(final TestInfo deviceTest) throws Exception {
         final String sender = deviceTest.getTestName();
         // {@link EventType#EXTRA_EVENT_TIME} will be recorded at device side.
diff --git a/hostsidetests/media/Android.mk b/hostsidetests/media/Android.mk
index db83686..4823ec8 100644
--- a/hostsidetests/media/Android.mk
+++ b/hostsidetests/media/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MODULE := CtsMediaHostTestCases
 
diff --git a/hostsidetests/media/app/MediaSessionTest/Android.mk b/hostsidetests/media/app/MediaSessionTest/Android.mk
index 7303147..174a744 100644
--- a/hostsidetests/media/app/MediaSessionTest/Android.mk
+++ b/hostsidetests/media/app/MediaSessionTest/Android.mk
@@ -16,7 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsMediaSessionHostTestApp
 
diff --git a/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml b/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
index 18060e1..72d3e64 100644
--- a/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
+++ b/hostsidetests/media/app/MediaSessionTest/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.media.session.cts">
+    package="android.media.session.cts"
+    android:targetSandboxVersion="2">
 
     <uses-sdk android:minSdkVersion="26"/>
 
diff --git a/hostsidetests/media/app/MediaSessionTestHelper/Android.mk b/hostsidetests/media/app/MediaSessionTestHelper/Android.mk
index 871140a..514f86a 100644
--- a/hostsidetests/media/app/MediaSessionTestHelper/Android.mk
+++ b/hostsidetests/media/app/MediaSessionTestHelper/Android.mk
@@ -30,7 +30,7 @@
     $(call all-java-files-under, ../../common)
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsMediaSessionTestHelper
 
diff --git a/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java b/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
index d505394..74ec892 100644
--- a/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
+++ b/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
@@ -150,12 +150,17 @@
      * @param appFileName file name of the app.
      * @param userId user ID to install the app against.
      */
-    protected void installAppAsUser(String appFileName, int userId)
+    protected void installAppAsUser(String appFileName, int userId, boolean asInstantApp)
             throws FileNotFoundException, DeviceNotAvailableException {
         CLog.d("Installing app " + appFileName + " for user " + userId);
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         String result = getDevice().installPackageForUser(
-                buildHelper.getTestFile(appFileName), true, true, userId, "-t");
+                buildHelper.getTestFile(appFileName),
+                true,
+                true,
+                userId,
+                "-t",
+                asInstantApp ? "--instant" : "");
         assertNull("Failed to install " + appFileName + " for user " + userId + ": " + result,
                 result);
     }
diff --git a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
index 4e3fa16..a5aa998 100644
--- a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
+++ b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
@@ -24,6 +24,8 @@
 import android.media.cts.BaseMultiUserTest;
 import android.media.cts.MediaSessionTestHelperConstants;
 
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
 import android.platform.test.annotations.RequiresDevice;
 
 import com.android.ddmlib.Log.LogLevel;
@@ -81,8 +83,22 @@
     /**
      * Tests {@link MediaSessionManager#getActiveSessions} with the primary user.
      */
+    @AppModeInstant
     @RequiresDevice
-    public void testGetActiveSessions_primaryUser() throws Exception {
+    public void testGetActiveSessionsInstant_primaryUser() throws Exception {
+        testGetActiveSessions_primaryUser(true);
+    }
+
+    /**
+     * Tests {@link MediaSessionManager#getActiveSessions} with the primary user.
+     */
+    @AppModeFull
+    @RequiresDevice
+    public void testGetActiveSessionsFull_primaryUser() throws Exception {
+        testGetActiveSessions_primaryUser(false);
+    }
+
+    private void testGetActiveSessions_primaryUser(boolean instant) throws Exception {
         if (mNotificationListenerDisabled) {
             CLog.logAndDisplay(LogLevel.INFO,
                     "NotificationListener is disabled. Test won't run.");
@@ -91,10 +107,10 @@
         int primaryUserId = getDevice().getPrimaryUserId();
 
         setAllowGetActiveSessionForTest(true, primaryUserId);
-        installAppAsUser(DEVICE_SIDE_TEST_APK, primaryUserId);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, primaryUserId, instant);
         runTest("testGetActiveSessions_noMediaSessionFromMediaSessionTestHelper");
 
-        installAppAsUser(MEDIA_SESSION_TEST_HELPER_APK, primaryUserId);
+        installAppAsUser(MEDIA_SESSION_TEST_HELPER_APK, primaryUserId, false);
         sendControlCommand(primaryUserId, FLAG_CREATE_MEDIA_SESSION);
         runTest("testGetActiveSessions_noMediaSessionFromMediaSessionTestHelper");
 
@@ -105,8 +121,22 @@
     /**
      * Tests {@link MediaSessionManager#getActiveSessions} with additional users.
      */
+    @AppModeInstant
     @RequiresDevice
-    public void testGetActiveSessions_additionalUser() throws Exception {
+    public void testGetActiveSessionsInstant_additionalUser() throws Exception {
+        testGetActiveSessions_additionalUser(true);
+    }
+
+    /**
+     * Tests {@link MediaSessionManager#getActiveSessions} with additional users.
+     */
+    @AppModeFull
+    @RequiresDevice
+    public void testGetActiveSessionsFull_additionalUser() throws Exception {
+        testGetActiveSessions_additionalUser(false);
+    }
+
+    private void testGetActiveSessions_additionalUser(boolean instant) throws Exception {
         if (!canCreateAdditionalUsers(1)) {
             CLog.logAndDisplay(LogLevel.INFO,
                     "Cannot create a new user. Skipping multi-user test cases.");
@@ -120,7 +150,7 @@
 
         // Test if another user can get the session.
         int newUser = createAndStartUser();
-        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser, instant);
         setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
@@ -129,8 +159,23 @@
     /**
      * Tests {@link MediaSessionManager#getActiveSessions} with restricted profiles.
      */
+    @AppModeInstant
     @RequiresDevice
-    public void testGetActiveSessions_restrictedProfiles() throws Exception {
+    public void testGetActiveSessionsInstant_restrictedProfiles() throws Exception {
+        testGetActiveSessions_restrictedProfiles(true);
+    }
+
+    /**
+     * Tests {@link MediaSessionManager#getActiveSessions} with restricted profiles.
+     */
+    @AppModeFull
+    @RequiresDevice
+    public void testGetActiveSessionsFull_restrictedProfiles() throws Exception {
+        testGetActiveSessions_restrictedProfiles(false);
+    }
+
+    private void testGetActiveSessions_restrictedProfiles(boolean instant)
+            throws Exception {
         if (!canCreateAdditionalUsers(1)) {
             CLog.logAndDisplay(LogLevel.INFO,
                     "Cannot create a new user. Skipping multi-user test cases.");
@@ -145,7 +190,7 @@
         // Test if another restricted profile can get the session.
         // Remove the created user first not to exceed system's user number limit.
         int newUser = createAndStartRestrictedProfile(getDevice().getPrimaryUserId());
-        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser, instant);
         setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
@@ -154,8 +199,23 @@
     /**
      * Tests {@link MediaSessionManager#getActiveSessions} with managed profiles.
      */
+    @AppModeInstant
     @RequiresDevice
-    public void testGetActiveSessions_managedProfiles() throws Exception {
+    public void testGetActiveSessionsInstant_managedProfiles() throws Exception {
+        testGetActiveSessions_managedProfiles(true);
+    }
+
+    /**
+     * Tests {@link MediaSessionManager#getActiveSessions} with managed profiles.
+     */
+    @AppModeFull
+    @RequiresDevice
+    public void testGetActiveSessionsFull_managedProfiles() throws Exception {
+        testGetActiveSessions_managedProfiles(false);
+    }
+
+    private void testGetActiveSessions_managedProfiles(boolean instant)
+            throws Exception {
         if (!hasDeviceFeature("android.software.managed_users")) {
             CLog.logAndDisplay(LogLevel.INFO,
                     "Device doesn't support managed profiles. Test won't run.");
@@ -170,7 +230,7 @@
         // Test if another managed profile can get the session.
         // Remove the created user first not to exceed system's user number limit.
         int newUser = createAndStartManagedProfile(getDevice().getPrimaryUserId());
-        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, newUser, instant);
         setAllowGetActiveSessionForTest(true, newUser);
         runTestAsUser("testGetActiveSessions_noMediaSession", newUser);
         removeUser(newUser);
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 03659dc..5232372 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
@@ -20,6 +20,10 @@
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
+import static android.os.BatteryManager.BATTERY_PLUGGED_AC;
+import static android.os.BatteryManager.BATTERY_PLUGGED_USB;
+import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS;
+
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 
 import java.util.concurrent.CountDownLatch;
@@ -81,6 +85,9 @@
     protected static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE";
     protected static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT";
 
+    // TODO: Update BatteryManager.BATTERY_PLUGGED_ANY as @TestApi
+    public static final int BATTERY_PLUGGED_ANY =
+            BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
 
     private static final String NETWORK_STATUS_SEPARATOR = "\\|";
     private static final int SECOND_IN_MS = 1000;
@@ -817,11 +824,16 @@
 
     protected void turnBatteryOn() throws Exception {
         executeSilentShellCommand("cmd battery unplug");
+        executeSilentShellCommand("cmd battery set status "
+                + BatteryManager.BATTERY_STATUS_DISCHARGING);
         assertBatteryState(false);
     }
 
     protected void turnBatteryOff() throws Exception {
-        executeSilentShellCommand("cmd battery reset");
+        executeSilentShellCommand("cmd battery set ac " + BATTERY_PLUGGED_ANY);
+        executeSilentShellCommand("cmd battery set level 100");
+        executeSilentShellCommand("cmd battery set status "
+                + BatteryManager.BATTERY_STATUS_CHARGING);
         assertBatteryState(true);
     }
 
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
index 76332be..87f9d77 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -57,18 +57,22 @@
         }
     }
 
+    @Override
+    public boolean isSupported() throws Exception {
+        if (!isDozeModeEnabled()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Doze Mode");
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks.
      */
     public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
         if (!isSupported()) return;
 
-        if (!isDozeModeEnabled()) {
-            Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because "
-                    + "device does not support Doze Mode");
-            return;
-        }
-
         Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests");
         if (!setMeteredNetwork()) {
             Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because "
@@ -139,12 +143,6 @@
     public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
         if (!isSupported()) return;
 
-        if (!isDozeModeEnabled()) {
-            Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because "
-                    + "device does not support Doze Mode");
-            return;
-        }
-
         if (!setUnmeteredNetwork()) {
             Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network"
                     + " is metered");
@@ -211,11 +209,6 @@
         if (!isSupported()) {
             return;
         }
-        if (!isDozeModeEnabled()) {
-            Log.i(TAG, "Skipping " + getClass() + "." + getName()
-                    + "() because device does not support Doze Mode");
-            return;
-        }
 
         setBatterySaverMode(true);
         setDozeMode(true);
@@ -246,11 +239,6 @@
         if (!isSupported()) {
             return;
         }
-        if (!isDozeModeEnabled()) {
-            Log.i(TAG, "Skipping " + getClass() + "." + getName()
-                    + "() because device does not support Doze Mode");
-            return;
-        }
 
         setDozeMode(true);
         setAppIdle(true);
@@ -277,11 +265,6 @@
         if (!isSupported()) {
             return;
         }
-        if (!isDozeModeEnabled()) {
-            Log.i(TAG, "Skipping " + getClass() + "." + getName()
-                    + "() because device does not support Doze Mode");
-            return;
-        }
 
         setDozeMode(true);
         setAppIdle(true);
diff --git a/hostsidetests/os/Android.mk b/hostsidetests/os/Android.mk
index 1b806c9..932e2cf 100644
--- a/hostsidetests/os/Android.mk
+++ b/hostsidetests/os/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_CTS_TEST_PACKAGE := android.host.os
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/os/app/Android.mk b/hostsidetests/os/app/Android.mk
index bc70dec..31e2812 100644
--- a/hostsidetests/os/app/Android.mk
+++ b/hostsidetests/os/app/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_SDK_VERSION := current
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsDeviceOsTestApp
 
diff --git a/hostsidetests/os/app/AndroidManifest.xml b/hostsidetests/os/app/AndroidManifest.xml
index 4c4338b..fa9d9ae 100755
--- a/hostsidetests/os/app/AndroidManifest.xml
+++ b/hostsidetests/os/app/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.os.app">
+    package="android.os.app"
+    android:targetSandboxVersion="2">
 
     <application>
         <activity android:name=".TestNonExported"
diff --git a/hostsidetests/os/src/android/os/cts/OsHostTests.java b/hostsidetests/os/src/android/os/cts/OsHostTests.java
index e36b1c7..086f787 100644
--- a/hostsidetests/os/src/android/os/cts/OsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/OsHostTests.java
@@ -16,6 +16,8 @@
 
 package android.os.cts;
 
+import android.platform.test.annotations.AppModeFull;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.CollectingOutputReceiver;
@@ -82,6 +84,7 @@
      *
      * @throws Exception
      */
+    @AppModeFull(reason = "Error message is different for instant app (Activity does not exist)")
     public void testNonExportedActivities() throws Exception {
         // Attempt to launch the non-exported activity in the test app
         CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
diff --git a/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java b/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
index 5097df6..d4b34ce 100644
--- a/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
@@ -16,6 +16,9 @@
 
 package android.os.cts;
 
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestResult.TestStatus;
@@ -28,6 +31,7 @@
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
+import java.io.FileNotFoundException;
 import java.util.Map;
 
 public class StaticSharedLibsHostTests extends DeviceTestCase implements IBuildReceiver {
@@ -85,26 +89,35 @@
             = "android.os.lib.consumer";
 
     private CompatibilityBuildHelper mBuildHelper;
+    private boolean mInstantMode = false;
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
         mBuildHelper = new CompatibilityBuildHelper(buildInfo);
     }
 
-    public void testInstallSharedLibrary() throws Exception {
+    @AppModeInstant
+    public void testInstallSharedLibraryInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestInstallSharedLibrary();
+    }
+
+    @AppModeFull
+    public void testInstallSharedLibraryFullMode() throws Exception {
+        doTestInstallSharedLibrary();
+    }
+
+    private void doTestInstallSharedLibrary() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install version 1
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install version 2
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Uninstall version 1
             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
             // Uninstall version 2
@@ -118,13 +131,23 @@
         }
     }
 
-    public void testCannotInstallSharedLibraryWithMissingDependency() throws Exception {
+    @AppModeInstant
+    public void testCannotInstallSharedLibraryWithMissingDependencyInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCannotInstallSharedLibraryWithMissingDependency();
+    }
+
+    @AppModeFull
+    public void testCannotInstallSharedLibraryWithMissingDependencyFullMode() throws Exception {
+        doTestCannotInstallSharedLibraryWithMissingDependency();
+    }
+
+    private void doTestCannotInstallSharedLibraryWithMissingDependency() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
         try {
             // Install version 1 - should fail - no dependency
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNotNull(install(STATIC_LIB_PROVIDER1_APK));
         } finally {
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
@@ -137,14 +160,11 @@
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install the library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install the client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER1_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER1_APK));
             // Try to load code and resources
             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
                     "android.os.lib.consumer1.UseSharedLibraryTest",
@@ -156,16 +176,25 @@
         }
     }
 
-    public void testCannotUninstallUsedSharedLibrary1() throws Exception {
+    @AppModeInstant
+    public void testCannotUninstallUsedSharedLibrary1InstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCannotUninstallUsedSharedLibrary1();
+    }
+
+    @AppModeFull
+    public void testCannotUninstallUsedSharedLibrary1FullMode() throws Exception {
+        doTestCannotUninstallUsedSharedLibrary1();
+    }
+
+    private void doTestCannotUninstallUsedSharedLibrary1() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install the library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // The library dependency cannot be uninstalled
             assertNotNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG));
             // Now the library dependency can be uninstalled
@@ -178,20 +207,28 @@
         }
     }
 
-    public void testCannotUninstallUsedSharedLibrary2() throws Exception {
+    @AppModeInstant
+    public void testCannotUninstallUsedSharedLibrary2InstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCannotUninstallUsedSharedLibrary2();
+    }
+
+    @AppModeFull
+    public void testCannotUninstallUsedSharedLibrary2FullMode() throws Exception {
+        doTestCannotUninstallUsedSharedLibrary2();
+    }
+
+    private void doTestCannotUninstallUsedSharedLibrary2() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install the library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install the client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER1_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER1_APK));
             // The library cannot be uninstalled
             assertNotNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
             // Uninstall the client
@@ -207,24 +244,31 @@
         }
     }
 
-    public void testLibraryVersionsAndVersionCodesSameOrder() throws Exception {
+    @AppModeInstant
+    public void testLibraryVersionsAndVersionCodesSameOrderInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestLibraryVersionsAndVersionCodesSameOrder();
+    }
+
+    @AppModeFull
+    public void testLibraryVersionsAndVersionCodesSameOrderFullMode() throws Exception {
+        doTestLibraryVersionsAndVersionCodesSameOrder();
+    }
+
+    private void doTestLibraryVersionsAndVersionCodesSameOrder() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER3_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install library version 1 with version code 1
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install library version 2 with version code 4
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Shouldn't be able to install library version 3 with version code 3
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER3_APK), false, false));
+            assertNotNull(install(STATIC_LIB_PROVIDER3_APK));
         } finally {
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
@@ -233,30 +277,48 @@
         }
     }
 
-    public void testCannotInstallAppWithMissingLibrary() throws Exception {
+    @AppModeInstant
+    public void testCannotInstallAppWithMissingLibraryInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCannotInstallAppWithMissingLibrary();
+    }
+
+    @AppModeFull
+    public void testCannotInstallAppWithMissingLibraryFullMode() throws Exception {
+        doTestCannotInstallAppWithMissingLibrary();
+    }
+
+    private void doTestCannotInstallAppWithMissingLibrary() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
         try {
             // Shouldn't be able to install an app if a dependency lib is missing
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER1_APK), false, false));
+            assertNotNull(install(STATIC_LIB_CONSUMER1_APK));
         } finally {
             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
         }
     }
 
-    public void testCanReplaceLibraryIfVersionAndVersionCodeSame() throws Exception {
+    @AppModeInstant
+    public void testCanReplaceLibraryIfVersionAndVersionCodeSameInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCanReplaceLibraryIfVersionAndVersionCodeSame();
+    }
+
+    @AppModeFull
+    public void testCanReplaceLibraryIfVersionAndVersionCodeSameFullMode() throws Exception {
+        doTestCanReplaceLibraryIfVersionAndVersionCodeSame();
+    }
+
+    private void doTestCanReplaceLibraryIfVersionAndVersionCodeSame() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install a library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Cannot install the library (need to reinstall)
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNotNull(install(STATIC_LIB_PROVIDER1_APK));
             // Can reinstall the library if version and version code same
             assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
                     STATIC_LIB_PROVIDER1_APK), true, false));
@@ -266,19 +328,27 @@
         }
     }
 
-    public void testUninstallSpecificLibraryVersion() throws Exception {
+    @AppModeInstant
+    public void testUninstallSpecificLibraryVersionInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestUninstallSpecificLibraryVersion();
+    }
+
+    @AppModeFull
+    public void testUninstallSpecificLibraryVersionFullMode() throws Exception {
+        doTestUninstallSpecificLibraryVersion();
+    }
+
+    private void doTestUninstallSpecificLibraryVersion() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install library version 1 with version code 1
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install library version 2 with version code 4
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Uninstall the library package with version code 4 (version 2)
             assertTrue(getDevice().executeShellCommand("pm uninstall --versionCode 4 "
                     + STATIC_LIB_PROVIDER1_PKG).startsWith("Success"));
@@ -291,20 +361,28 @@
         }
     }
 
-    public void testKeyRotation() throws Exception {
+    @AppModeInstant
+    public void testKeyRotationInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestKeyRotation();
+    }
+
+    @AppModeFull
+    public void testKeyRotationFullMode() throws Exception {
+        doTestKeyRotation();
+    }
+
+    private void doTestKeyRotation() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
         try {
             // Install a library version specifying an upgrade key set
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Install a newer library signed with the upgrade key set
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER4_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER4_APK));
             // Install a client that depends on the upgraded key set
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER2_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER2_APK));
             // Ensure code and resources can be loaded
             runDeviceTests(STATIC_LIB_CONSUMER2_PKG,
                     "android.os.lib.consumer2.UseSharedLibraryTest",
@@ -316,20 +394,28 @@
         }
     }
 
-    public void testCannotInstallIncorrectlySignedLibrary() throws Exception {
+    @AppModeInstant
+    public void testCannotInstallIncorrectlySignedLibraryInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestCannotInstallIncorrectlySignedLibrary();
+    }
+
+    @AppModeFull
+    public void testCannotInstallIncorrectlySignedLibraryFullMode() throws Exception {
+        doTestCannotInstallIncorrectlySignedLibrary();
+    }
+
+    private void doTestCannotInstallIncorrectlySignedLibrary() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install a library version not specifying an upgrade key set
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Shouldn't be able to install a newer version signed differently
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER4_APK), false, false));
+            assertNotNull(install(STATIC_LIB_PROVIDER4_APK));
         } finally {
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
             getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
@@ -337,13 +423,23 @@
         }
     }
 
-    public void testLibraryAndPackageNameCanMatch() throws Exception {
+    @AppModeInstant
+    public void testLibraryAndPackageNameCanMatchInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestLibraryAndPackageNameCanMatch();
+    }
+
+    @AppModeFull
+    public void testLibraryAndPackageNameCanMatchFullMode() throws Exception {
+        doTestLibraryAndPackageNameCanMatch();
+    }
+
+    private void doTestLibraryAndPackageNameCanMatch() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER5_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER6_PKG);
         try {
             // Install a library with same name as package should work.
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER5_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER5_APK));
             // Install a library with same name as package should work.
             assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
                     STATIC_LIB_PROVIDER6_APK), true, false));
@@ -353,7 +449,18 @@
         }
     }
 
-    public void testGetSharedLibraries() throws Exception {
+    @AppModeInstant
+    public void testGetSharedLibrariesInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestGetSharedLibraries();
+    }
+
+    @AppModeFull
+    public void testGetSharedLibrariesFullMode() throws Exception {
+        doTestGetSharedLibraries();
+    }
+
+    private void doTestGetSharedLibraries() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
@@ -362,23 +469,17 @@
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install the first library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install the second library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Install the third library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER4_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER4_APK));
             // Install the first client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER1_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER1_APK));
             // Install the second client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER2_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER2_APK));
             // Ensure libraries are properly reported
             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
                     "android.os.lib.consumer1.UseSharedLibraryTest",
@@ -393,24 +494,31 @@
         }
     }
 
-    public void testAppCanSeeOnlyLibrariesItDependOn() throws Exception {
+    @AppModeInstant
+    public void testAppCanSeeOnlyLibrariesItDependOnInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestAppCanSeeOnlyLibrariesItDependOn();
+    }
+
+    @AppModeFull
+    public void testAppCanSeeOnlyLibrariesItDependOnFullMode() throws Exception {
+        doTestAppCanSeeOnlyLibrariesItDependOn();
+    }
+
+    private void doTestAppCanSeeOnlyLibrariesItDependOn() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
         try {
             // Install library dependency
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER_RECURSIVE_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
             // Install the first library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER1_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER1_APK));
             // Install the second library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER2_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER2_APK));
             // Install the client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER1_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER1_APK));
             // Ensure the client can see only the lib it depends on
             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
                     "android.os.lib.consumer1.UseSharedLibraryTest",
@@ -423,16 +531,25 @@
         }
     }
 
-    public void testLoadCodeFromNativeLib() throws Exception {
+    @AppModeInstant
+    public void testLoadCodeFromNativeLibInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestLoadCodeFromNativeLib();
+    }
+
+    @AppModeFull
+    public void testLoadCodeFromNativeLibFullMode() throws Exception {
+        doTestLoadCodeFromNativeLib();
+    }
+
+    private void doTestLoadCodeFromNativeLib() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_NATIVE_CONSUMER_PKG);
         getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG);
         try {
             // Install library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_NATIVE_PROVIDER_APK), false, false));
+            assertNull(install(STATIC_LIB_NATIVE_PROVIDER_APK));
             // Install the library client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_NATIVE_CONSUMER_APK), false, false));
+            assertNull(install(STATIC_LIB_NATIVE_CONSUMER_APK));
             // Ensure the client can load native code from the library
             runDeviceTests(STATIC_LIB_NATIVE_CONSUMER_PKG,
                     "android.os.lib.consumer.UseSharedLibraryTest",
@@ -443,28 +560,47 @@
         }
     }
 
-    public void testLoadCodeFromNativeLibMultiArchViolation() throws Exception {
+    @AppModeInstant
+    public void testLoadCodeFromNativeLibMultiArchViolationInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestLoadCodeFromNativeLibMultiArchViolation();
+    }
+
+    @AppModeFull
+    public void testLoadCodeFromNativeLibMultiArchViolationFullMode() throws Exception {
+        doTestLoadCodeFromNativeLibMultiArchViolation();
+    }
+
+    private void doTestLoadCodeFromNativeLibMultiArchViolation() throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG1);
         try {
             // Cannot install the library with native code if not multi-arch
-            assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_NATIVE_PROVIDER_APK1), false, false));
+            assertNotNull(install(STATIC_LIB_NATIVE_PROVIDER_APK1));
         } finally {
             getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG1);
         }
     }
 
-    public void testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts()
+    @AppModeInstant
+    public void testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsInstantMode() throws Exception {
+        mInstantMode = true;
+        doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts();
+    }
+
+    @AppModeFull
+    public void testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsFullMode() throws Exception {
+        doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts();
+    }
+
+    private void doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts()
             throws Exception {
         getDevice().uninstallPackage(STATIC_LIB_CONSUMER3_PKG);
         getDevice().uninstallPackage(STATIC_LIB_PROVIDER7_PKG);
         try {
             // Install the library
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_PROVIDER7_APK), false, false));
+            assertNull(install(STATIC_LIB_PROVIDER7_APK));
             // Install the client
-            assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
-                    STATIC_LIB_CONSUMER3_APK), false, false));
+            assertNull(install(STATIC_LIB_CONSUMER3_APK));
             // Try to load code and resources
             runDeviceTests(STATIC_LIB_CONSUMER3_PKG,
                     "android.os.lib.consumer3.UseSharedLibraryTest",
@@ -506,4 +642,9 @@
             throw new AssertionError(errorBuilder.toString());
         }
     }
+
+    private String install(String apk) throws DeviceNotAvailableException, FileNotFoundException {
+        return getDevice().installPackage(mBuildHelper.getTestFile(apk), false, false,
+                apk.contains("consumer") && mInstantMode ? "--instant" : "");
+    }
 }
diff --git a/hostsidetests/os/test-apps/Android.mk b/hostsidetests/os/test-apps/Android.mk
index bd94fb5..0767e4b 100644
--- a/hostsidetests/os/test-apps/Android.mk
+++ b/hostsidetests/os/test-apps/Android.mk
@@ -17,7 +17,7 @@
 include $(CLEAR_VARS)
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 # Build the test APKs using their own makefiles
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/os/test-apps/ProcfsTestApp/Android.mk b/hostsidetests/os/test-apps/ProcfsTestApp/Android.mk
index d3edc43..e42804f 100644
--- a/hostsidetests/os/test-apps/ProcfsTestApp/Android.mk
+++ b/hostsidetests/os/test-apps/ProcfsTestApp/Android.mk
@@ -26,6 +26,6 @@
 LOCAL_PACKAGE_NAME := CtsHostProcfsTestApp
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/os/test-apps/ProcfsTestApp/AndroidManifest.xml b/hostsidetests/os/test-apps/ProcfsTestApp/AndroidManifest.xml
index 8a7463a..57453c6 100755
--- a/hostsidetests/os/test-apps/ProcfsTestApp/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/ProcfsTestApp/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.os.procfs">
+    package="android.os.procfs"
+    android:targetSandboxVersion="2">
 
     <application>
         <activity android:name=".ProcfsTest"
diff --git a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp1/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp1/AndroidManifest.xml
index a1550a6..52a2dfe 100755
--- a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp1/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp1/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.os.lib.consumer1"
         android:versionCode="1"
-        android:versionName="1.0">
+        android:versionName="1.0"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
 
diff --git a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp2/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp2/AndroidManifest.xml
index ae2527b..7ddb841 100755
--- a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp2/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp2/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.os.lib.consumer2"
         android:versionCode="2"
-        android:versionName="3.0">
+        android:versionName="3.0"
+        android:targetSandboxVersion="2">
 
     <application>
         <uses-static-library
diff --git a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp3/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp3/AndroidManifest.xml
index daddbc6..b156e6b 100755
--- a/hostsidetests/os/test-apps/StaticSharedLibConsumerApp3/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/StaticSharedLibConsumerApp3/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.os.lib.consumer3"
         android:versionCode="2"
-        android:versionName="3.0">
+        android:versionName="3.0"
+        android:targetSandboxVersion="2">
 
     <application>
         <uses-static-library
diff --git a/hostsidetests/sample/Android.mk b/hostsidetests/sample/Android.mk
index bc821ae..1b9bd44 100644
--- a/hostsidetests/sample/Android.mk
+++ b/hostsidetests/sample/Android.mk
@@ -21,12 +21,12 @@
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MODULE := CtsSampleHostTestCases
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
 
-include $(BUILD_HOST_JAVA_LIBRARY)
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/sample/app/Android.mk b/hostsidetests/sample/app/Android.mk
index b3b6ad1..bc271b6 100644
--- a/hostsidetests/sample/app/Android.mk
+++ b/hostsidetests/sample/app/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsSampleDeviceApp
 
diff --git a/hostsidetests/sample/app2/Android.mk b/hostsidetests/sample/app2/Android.mk
index 845f51a..cec0078 100644
--- a/hostsidetests/sample/app2/Android.mk
+++ b/hostsidetests/sample/app2/Android.mk
@@ -30,10 +30,10 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsSampleDeviceApp2
 
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/sample/app2/AndroidManifest.xml b/hostsidetests/sample/app2/AndroidManifest.xml
index 7d65c30..3bbcf1f 100644
--- a/hostsidetests/sample/app2/AndroidManifest.xml
+++ b/hostsidetests/sample/app2/AndroidManifest.xml
@@ -16,8 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.sample.cts.app2">
-
+          package="android.sample.cts.app2"
+          android:targetSandboxVersion="2">
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java b/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java
index 8299d479..918632e 100644
--- a/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java
+++ b/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java
@@ -16,10 +16,8 @@
 
 package android.sample.cts.app2;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Assume;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java
index 0fbf3b9..e8ae1f0 100644
--- a/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java
@@ -16,6 +16,9 @@
 
 package android.sample.cts;
 
+import android.platform.test.annotations.AppModeInstant;
+import android.platform.test.annotations.AppModeFull;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
@@ -34,7 +37,6 @@
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class SampleHostJUnit4DeviceTest extends BaseHostJUnit4Test {
-
     private static final String TEST_PKG = "android.sample.cts.app2";
     private static final String TEST_CLASS = TEST_PKG + "." + "SampleDeviceTest";
     private static final String TEST_APP = "CtsSampleDeviceApp2.apk";
@@ -45,21 +47,48 @@
 
     @Before
     public void setUp() throws Exception {
-        installPackage(TEST_APP);
+        uninstallPackage(getDevice(), TEST_PKG);
     }
 
     @Test
-    public void testRunDeviceTestsPasses() throws Exception {
+    @AppModeInstant
+    public void testRunDeviceTestsPassesInstant() throws Exception {
+        installPackage(true);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_PASSES));
+    }
+
+    @Test
+    @AppModeFull
+    public void testRunDeviceTestsPassesFull() throws Exception {
+        installPackage(false);
         Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_PASSES));
     }
 
     @Test(expected=AssertionError.class)
-    public void testRunDeviceTestsFails() throws Exception {
+    @AppModeInstant
+    public void testRunDeviceTestsFailsInstant() throws Exception {
+        installPackage(true);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_FAILS));
+    }
+
+    @Test(expected=AssertionError.class)
+    @AppModeFull
+    public void testRunDeviceTestsFailsFull() throws Exception {
+        installPackage(false);
         Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_FAILS));
     }
 
     @Test
-    public void testRunDeviceTestsAssumeFails() throws Exception {
+    @AppModeInstant
+    public void testRunDeviceTestsAssumeFailsInstant() throws Exception {
+        installPackage(true);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_ASSUME_FAILS));
+    }
+
+    @Test
+    @AppModeFull
+    public void testRunDeviceTestsAssumeFailsFull() throws Exception {
+        installPackage(false);
         Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_ASSUME_FAILS));
     }
 
@@ -68,4 +97,8 @@
         uninstallPackage(getDevice(), TEST_PKG);
     }
 
+    private void installPackage(boolean instant) throws Exception {
+        installPackage(TEST_APP, instant ? new String[]{"--instant"} : new String[0]);
+    }
+
 }
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index 229bf11..43d9f45 100755
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -50,6 +50,7 @@
 
         <!-- Bulletin 2016-09 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2015-8839->/data/local/tmp/CVE-2015-8839" />
         <option name="push" value="CVE-2016-2471->/data/local/tmp/CVE-2016-2471" />
 
         <!--__________________-->
@@ -67,6 +68,7 @@
         <!--__________________-->
         <!-- Bulletin 2017-01 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-0386->/data/local/tmp/CVE-2017-0386" />
 
         <!--__________________-->
         <!-- Bulletin 2017-02 -->
@@ -84,6 +86,7 @@
         <!--__________________-->
         <!-- Bulletin 2017-04 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2014-3145->/data/local/tmp/CVE-2014-3145"/>
         <option name="push" value="CVE-2017-0553->/data/local/tmp/CVE-2017-0553"/>
 
         <!--__________________-->
@@ -97,6 +100,7 @@
         <!--__________________-->
         <!-- Bulletin 2017-07 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2016-2109->/data/local/tmp/CVE-2016-2109"/>
 
         <!--__________________-->
         <!-- Bulletin 2017-08 -->
diff --git a/hostsidetests/security/res/cve_2016_3916.apk b/hostsidetests/security/res/cve_2016_3916.apk
new file mode 100644
index 0000000..96c6128
--- /dev/null
+++ b/hostsidetests/security/res/cve_2016_3916.apk
Binary files differ
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/hostsidetests/security/securityPatch/CVE-2014-3145/Android.mk
similarity index 60%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to hostsidetests/security/securityPatch/CVE-2014-3145/Android.mk
index e6ee38f..30cae16 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2014-3145/Android.mk
@@ -15,16 +15,16 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_MODULE := CVE-2014-3145
+LOCAL_SRC_FILES := poc.c
 LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
-include $(BUILD_CTS_PACKAGE)
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS = -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2014-3145/poc.c b/hostsidetests/security/securityPatch/CVE-2014-3145/poc.c
new file mode 100644
index 0000000..852374f
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2014-3145/poc.c
@@ -0,0 +1,137 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#define ARRAY_SIZE(__a) (sizeof(__a) / sizeof((__a)[0]))
+#include <errno.h>
+#include <linux/filter.h>
+#include <linux/netlink.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static struct sock_filter nlattr[] = {
+  { 0000, 0, 0, 0x87654321 },
+  { 0x01, 0, 0, 0x0000002a },
+  { 0x20, 0, 0, 0xfffff00c },
+  { 0x16, 0, 0, 0000000000 },
+};
+
+static struct sock_fprog bpf_nlattr = {
+  .len = ARRAY_SIZE(nlattr),
+  .filter = nlattr,
+};
+
+static struct sock_filter nlattr_nest[] = {
+  { 0000, 0, 0, 0x87654321 },
+  { 0x01, 0, 0, 0x0000002a },
+  { 0x20, 0, 0, 0xfffff010 },
+  { 0x16, 0, 0, 0000000000 },
+};
+
+static struct sock_fprog bpf_nlattr_nest = {
+  .len = ARRAY_SIZE(nlattr_nest),
+  .filter = nlattr_nest,
+};
+
+static struct sock_filter nest_rem[] = {
+  { 0000, 0, 0, 0000000000 },
+  { 0x01, 0, 0, 0x0000002a },
+  { 0x20, 0, 0, 0xfffff010 },
+  { 0x16, 0, 0, 0000000000 },
+};
+
+static struct sock_fprog bpf_nest_rem = {
+  .len = ARRAY_SIZE(nest_rem),
+  .filter = nest_rem,
+};
+
+static int send_receive_packet(int s[2], const void* pkt, int len)
+{
+  char tmp[1024];
+  ssize_t ret;
+
+  ret = send(s[1], pkt, len, 0);
+  if (ret != len) {
+    return -1;
+  }
+
+  ret = recv(s[0], tmp, len, MSG_DONTWAIT);
+  if (ret < 0 && errno == EAGAIN)
+    return 0;
+
+  return 1;
+}
+
+int main()
+{
+  struct nlattr chkrem[2] = {
+    [0] = {
+        .nla_len = 0xfff0,
+        .nla_type = 0,
+    },
+    [1] = {
+        .nla_len = sizeof(struct nlattr),
+        .nla_type = 42,
+    },
+  };
+  __u16 chksz = 0xfefe;
+  int s[2], ret;
+
+  ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, s);
+  if (ret) {
+    return -1;
+  }
+
+  ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
+      &bpf_nlattr, sizeof(bpf_nlattr));
+  if (ret < 0) {
+    return -1;
+  }
+
+  ret = send_receive_packet(s, &chksz, sizeof(chksz));
+  if (ret) {
+    ret = 113;
+    goto out;
+  }
+
+  ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
+      &bpf_nlattr_nest, sizeof(bpf_nlattr_nest));
+  if (ret < 0) {
+    return -1;
+  }
+
+  ret = send_receive_packet(s, &chksz, sizeof(chksz));
+  if (ret) {
+    ret = 113;
+    goto out;
+  }
+
+  ret = setsockopt(s[0], SOL_SOCKET, SO_ATTACH_FILTER,
+      &bpf_nest_rem, sizeof(bpf_nest_rem));
+  if (ret < 0) {
+    return -1;
+  }
+
+  ret = send_receive_packet(s, chkrem, sizeof(chkrem));
+  if(ret){
+    ret = 113;
+  }
+
+out:
+  return ret;
+}
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/hostsidetests/security/securityPatch/CVE-2015-8839/Android.mk
old mode 100644
new mode 100755
similarity index 61%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to hostsidetests/security/securityPatch/CVE-2015-8839/Android.mk
index e6ee38f..65fe025
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2015-8839/Android.mk
@@ -15,16 +15,22 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_MODULE := CVE-2015-8839
+LOCAL_SRC_FILES := poc.c
+
+LOCAL_SHARED_LIBRARIES := libcutils \
+                          liblog
+
 LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
-include $(BUILD_CTS_PACKAGE)
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2015-8839/poc.c b/hostsidetests/security/securityPatch/CVE-2015-8839/poc.c
new file mode 100755
index 0000000..fb05773
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2015-8839/poc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <cutils/log.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/falloc.h>
+#include <linux/magic.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+
+static int parse_kernel_release(long *const major, long *const minor) {
+  struct utsname buffer;
+  if (uname(&buffer) == -1) {
+    return -1;
+  }
+  return sscanf(buffer.release, "%ld.%ld", major, minor) == 2;
+}
+
+int main(void) {
+  long major = 0, minor = 0;
+  int fd = -1, result = -1;
+  char tmpFile[32];
+  struct statfs sfs;
+
+  memset(tmpFile, 0, sizeof(tmpFile));
+  strncpy(tmpFile, "/data/local/tmp/tmpFile", 24);
+
+  // check the kernel version
+  parse_kernel_release(&major, &minor);
+
+  // Kernels less than 4.1 are affected
+  if (major < 4 || (major == 4 && minor < 1)) {
+    fd = open(tmpFile, O_WRONLY | O_APPEND | O_CREAT, 0644);
+    if (fd < 0) {
+      ALOGE("Creation of tmp file is failed [%s]", strerror(errno));
+      return -1;
+    }
+
+    fstatfs(fd, &sfs);
+    if (sfs.f_type == EXT4_SUPER_MAGIC) {
+      result = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 1);
+      if (result < 0 && errno == EOPNOTSUPP) {
+        ALOGD("fallocate result [%s] errno [%d]", strerror(errno), errno);
+        ALOGE("fallocate result EOPNOTSUPP");
+      }
+    }
+    if (fd)
+      close(fd);
+  }
+  return 0;
+}
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-2109/Android.mk
similarity index 64%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to hostsidetests/security/securityPatch/CVE-2016-2109/Android.mk
index e6ee38f..02f49d0 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/hostsidetests/security/securityPatch/CVE-2016-2109/Android.mk
@@ -15,16 +15,18 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_MODULE := CVE-2016-2109
+LOCAL_SRC_FILES := poc.c
 LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_SHARED_LIBRARIES := libcrypto
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
 
-include $(BUILD_CTS_PACKAGE)
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS = -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-2109/poc.c b/hostsidetests/security/securityPatch/CVE-2016-2109/poc.c
new file mode 100644
index 0000000..0ae6512
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2016-2109/poc.c
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+unsigned char bad_bio[] = {
+  0x30, 0x84, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff
+};
+
+
+X509 *cert;
+
+int main(void){
+  unsigned long err = 0;
+  ERR_load_crypto_strings();
+  BIO *in = BIO_new(BIO_s_mem());
+  if(in != NULL){
+    BIO_write(in, bad_bio, sizeof(bad_bio));
+    cert = d2i_X509_bio(in, NULL); // x509 should be present on all Android systems
+    BIO_free(in);
+    if(cert != NULL){
+      X509_free(cert);
+    }
+    if((err = ERR_get_error())
+        == 0x07000041) // malloc error
+      return 113;
+  }
+}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0386/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0386/Android.mk
new file mode 100755
index 0000000..4c7a1ae
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2017-0386/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2017-0386
+
+LOCAL_SHARED_LIBRARIES := libnl \
+                          libc \
+                          liblog
+
+LOCAL_SRC_FILES := poc.c
+LOCAL_C_INCLUDES := external/libnl/include
+
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_LDFLAGS += -fPIE -pie
+LOCAL_LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0386/poc.c b/hostsidetests/security/securityPatch/CVE-2017-0386/poc.c
new file mode 100755
index 0000000..dae2d79
--- /dev/null
+++ b/hostsidetests/security/securityPatch/CVE-2017-0386/poc.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <log/log.h>
+
+#include <netlink/msg.h>
+#include <netlink/netlink.h>
+#include <netlink-private/object-api.h>
+#include <netlink-private/types.h>
+#include <netlink/object.h>
+#include <netlink/attr.h>
+
+int main(void) {
+  struct nl_msg *message = NULL;
+  char *pad = NULL, *pad2 = NULL;
+  uint32_t result = 0;
+
+  message = nlmsg_alloc();
+  if (message == NULL) {
+    ALOGE("Alloc message memory failed");
+    goto ret;
+  }
+
+  ALOGI("nl_msg.nm_size : %zx\n", message->nm_size);
+
+  struct nlmsghdr *hdr;
+  hdr = message->nm_nlh;
+
+  int length = 0x1000 + 12 - 0x30;
+  pad = malloc(length);
+  if (pad == NULL) {
+    ALOGE("Alloc pad memory failed");
+    goto ret;
+  }
+  memset(pad, 0x41, length);
+
+  pad2 = malloc(0x1000);
+  if (pad2 == NULL) {
+    ALOGE("Alloc pad2 memory failed");
+    goto ret;
+  }
+  memset(pad2, 0x33, 0x1000);
+
+  nla_put(message, 0x4444, length, pad);
+  result = message->nm_nlh->nlmsg_len;
+
+  ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
+  ALOGI("message len = 0x%x", message->nm_nlh->nlmsg_len);
+
+  nla_put(message, 0x8888, 0xFFFFF000, pad2);
+  ALOGI("\n\n\nPutting down overflow.......\n\n\n");
+
+  ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
+  ALOGI("message len = 0x%x", message->nm_nlh->nlmsg_len);
+
+  if(result == message->nm_nlh->nlmsg_len) {
+    ALOGE("No Integer overflow");
+  } else {
+    ALOGE("Integer overflow happened");
+  }
+
+ret:
+  if(NULL != pad) free(pad);
+  if(NULL != pad2) free(pad2);
+  return 0;
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_09.java b/hostsidetests/security/src/android/security/cts/Poc16_09.java
index 7ab08ad..676862f 100644
--- a/hostsidetests/security/src/android/security/cts/Poc16_09.java
+++ b/hostsidetests/security/src/android/security/cts/Poc16_09.java
@@ -26,4 +26,16 @@
     public void testPocCVE_2016_2471() throws Exception {
         AdbUtils.runPoc("CVE-2016-2471", getDevice(), 60);
     }
+
+    /**
+     *  b/28760453
+     */
+    @SecurityTest
+    public void testPocCVE_2015_8839() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPoc("CVE-2015-8839", getDevice(), 60);
+
+        String logcat =  AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertMatches("[\\s\\n\\S]*fallocate result EOPNOTSUPP[\\s\\n\\S]*", logcat);
+    }
 }
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_10.java b/hostsidetests/security/src/android/security/cts/Poc16_10.java
index 0c9a5b3..5641aee 100644
--- a/hostsidetests/security/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/security/src/android/security/cts/Poc16_10.java
@@ -90,4 +90,21 @@
             AdbUtils.runPoc("CVE-2016-6736", getDevice(), 60);
         }
     }
+
+    /**
+     *  b/30741779
+     */
+    @SecurityTest
+    public void testPocCVE_2016_3916() throws Exception {
+        AdbUtils.installApk("/cve_2016_3916.apk", getDevice());
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+
+         AdbUtils.runCommandLine("am start -n com.trendmicro.wish_wu.camera2/" +
+                                 "com.trendmicro.wish_wu.camera2.Camera2TestActivity", getDevice());
+        Thread.sleep(10000);
+        String logcat =  AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatches("[\\s\\n\\S]*Fatal signal 11 \\(SIGSEGV\\)" +
+                "[\\s\\n\\S]*>>> /system/bin/" +
+                "mediaserver <<<[\\s\\n\\S]*", logcat);
+    }
 }
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_01.java b/hostsidetests/security/src/android/security/cts/Poc17_01.java
index 4fd98b7..3f69e38 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_01.java
@@ -30,4 +30,16 @@
             AdbUtils.runPoc("CVE-2016-8482", getDevice(), 60);
         }
     }
+
+    /**
+     *  b/32255299
+     */
+    @SecurityTest
+    public void testPocCVE_2017_0386() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPoc("CVE-2017-0386", getDevice(), 60);
+
+        String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertMatches("[\\s\\n\\S]*No Integer overflow[\\s\\n\\S]*", logcat);
+    }
 }
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_04.java b/hostsidetests/security/src/android/security/cts/Poc17_04.java
index c3bd3eb..d547a8f 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_04.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_04.java
@@ -31,4 +31,13 @@
     assertFalse("Segfault found",
         AdbUtils.runCommandGetExitCode("/data/local/tmp/CVE-2017-0553", getDevice())==139);
   }
- }
+
+  /**
+   * b/72460737
+   */
+  @SecurityTest
+  public void testPocCVE_2014_3145() throws Exception {
+    assertFalse("VULNERABLE DEVICE DETECTED",
+                AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
+  }
+}
diff --git a/tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java b/hostsidetests/security/src/android/security/cts/Poc17_07.java
similarity index 60%
copy from tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
copy to hostsidetests/security/src/android/security/cts/Poc17_07.java
index 229ed1f..1f9602a4 100644
--- a/tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_07.java
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,7 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.jobscheduler.cts.shareduid;
 
-public class Empty {
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+@SecurityTest
+public class Poc17_07 extends SecurityTestCase {
+
+    /**
+     * b/35443725
+     **/
+    @SecurityTest
+    public void testPocCVE_2016_2109() throws Exception {
+      assertFalse("Overallocation detected!",
+          AdbUtils.runPocCheckExitCode("CVE-2016-2109",
+            getDevice(), 60));
+    }
+
 }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 0e0ee76..1bfe778 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -338,6 +338,31 @@
         assertTrue(a1.getState().getNumber() == stateOff);
     }
 
+    public void testOverlayState() throws Exception {
+        final int atomTag = Atom.OVERLAY_STATE_CHANGED_FIELD_NUMBER;
+
+        Set<Integer> entered = new HashSet<>(
+                Arrays.asList(OverlayStateChanged.State.ENTERED_VALUE));
+        Set<Integer> exited = new HashSet<>(
+                Arrays.asList(OverlayStateChanged.State.EXITED_VALUE));
+
+        // Add state sets to the list in order.
+        List<Set<Integer>> stateSet = Arrays.asList(entered, exited);
+
+        createAndUploadConfig(atomTag, false);
+
+        runActivity("StatsdCtsForegroundActivity", "action", "action.show_application_overlay",
+                3_000);
+
+        // Sorted list of events in order in which they occurred.
+        List<EventMetricData> data = getEventMetricDataList();
+
+        // Assert that the events happened in the expected order.
+        // The overlay box should appear about 2sec after the app start
+        assertStatesOccurred(stateSet, data, 0,
+                atom -> atom.getOverlayStateChanged().getState().getNumber());
+    }
+
     public void testDavey() throws Exception {
         if (!DAVEY_ENABLED ) return;
         long MAX_DURATION = 2000;
@@ -630,31 +655,6 @@
                 atom -> atom.getPictureInPictureStateChanged().getState().getNumber());
     }
 
-    public void testOverlayState() throws Exception {
-        final int atomTag = Atom.OVERLAY_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> entered = new HashSet<>(
-                Arrays.asList(OverlayStateChanged.State.ENTERED_VALUE));
-        Set<Integer> exited = new HashSet<>(
-                Arrays.asList(OverlayStateChanged.State.EXITED_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(entered, exited);
-
-        createAndUploadConfig(atomTag, false);
-
-        runActivity("StatsdCtsForegroundActivity", "action", "action.show_application_overlay",
-                3_000);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        // The overlay box should appear about 2sec after the app start
-        assertStatesOccurred(stateSet, data, 0,
-                atom -> atom.getOverlayStateChanged().getState().getNumber());
-    }
-
     public void testAppCrashOccurred() throws Exception {
         final int atomTag = Atom.APP_CRASH_OCCURRED_FIELD_NUMBER;
         createAndUploadConfig(atomTag, false);
diff --git a/hostsidetests/ui/Android.mk b/hostsidetests/ui/Android.mk
index af7e2c9..90fdad2 100644
--- a/hostsidetests/ui/Android.mk
+++ b/hostsidetests/ui/Android.mk
@@ -31,7 +31,7 @@
 LOCAL_CTS_TEST_PACKAGE := android.ui.cts
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := general-tests cts_instant
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/ui/appA/Android.mk b/hostsidetests/ui/appA/Android.mk
index 3abc7a0..cf6df92 100644
--- a/hostsidetests/ui/appA/Android.mk
+++ b/hostsidetests/ui/appA/Android.mk
@@ -32,6 +32,6 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/appA/AndroidManifest.xml b/hostsidetests/ui/appA/AndroidManifest.xml
index dd2a901..155e0af 100644
--- a/hostsidetests/ui/appA/AndroidManifest.xml
+++ b/hostsidetests/ui/appA/AndroidManifest.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2012 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,23 +15,29 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.taskswitching.appa">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+        package="android.taskswitching.appa"
+        android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner" />
 
         <activity
             android:name=".AppAActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
             android:screenOrientation="portrait" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
 
-                <category android:name="android.intent.category.LAUNCHER" />
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="foo.com" />
+                <data android:path="/appa" />
             </intent-filter>
+
         </activity>
     </application>
 
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.taskswitching.appa" />
+
 </manifest>
diff --git a/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java b/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java
index 32ccfc1..2fe49ac 100644
--- a/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java
+++ b/hostsidetests/ui/appA/src/android/taskswitching/appa/AppAActivity.java
@@ -17,10 +17,9 @@
 package android.taskswitching.appa;
 
 import android.app.ListActivity;
-import android.content.Intent;
-
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.RemoteCallback;
 import android.view.WindowManager;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
@@ -30,9 +29,7 @@
  * This is for measuring taskswitching time between two apps.
  */
 public class AppAActivity extends ListActivity {
-    static final String TAG = "AppAActivity";
     private static final int NUMBER_ELEMENTS = 1000;
-    private static final String TASKSWITCHING_INTENT = "android.taskswitching.appa";
     private Handler mHandler;
 
     private String[] mItems = new String[NUMBER_ELEMENTS];
@@ -53,13 +50,8 @@
     @Override
     public void onResume() {
         super.onResume();
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                Intent intent = new Intent(TASKSWITCHING_INTENT);
-                sendBroadcast(intent);
-            }
+        mHandler.post(() -> {
+            getIntent().<RemoteCallback>getParcelableExtra("callback").sendResult(null);
         });
     }
 }
diff --git a/hostsidetests/ui/appB/Android.mk b/hostsidetests/ui/appB/Android.mk
index 4501cf3..6c64244 100644
--- a/hostsidetests/ui/appB/Android.mk
+++ b/hostsidetests/ui/appB/Android.mk
@@ -32,6 +32,6 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/appB/AndroidManifest.xml b/hostsidetests/ui/appB/AndroidManifest.xml
index 9d99377..0cd5092 100644
--- a/hostsidetests/ui/appB/AndroidManifest.xml
+++ b/hostsidetests/ui/appB/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.taskswitching.appb">
+        package="android.taskswitching.appb"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
@@ -28,9 +29,18 @@
             android:screenOrientation="portrait" >
 
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER"/>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="foo.com" />
+                <data android:path="/appb" />
             </intent-filter>
+
         </activity>
     </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.taskswitching.appb" />
+
 </manifest>
diff --git a/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java b/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java
index ea7f52a..c799d46 100644
--- a/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java
+++ b/hostsidetests/ui/appB/src/android/taskswitching/appb/AppBActivity.java
@@ -17,9 +17,9 @@
 package android.taskswitching.appb;
 
 import android.app.ListActivity;
-import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.RemoteCallback;
 import android.view.WindowManager;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
@@ -29,9 +29,7 @@
  * This is for measuring taskswitching time between two apps.
  */
 public class AppBActivity extends ListActivity {
-    static final String TAG = "AppBActivity";
     private static final int NUMBER_ELEMENTS = 1000;
-    private static final String TASKSWITCHING_INTENT = "android.taskswitching.appb";
     private Handler mHandler;
 
     private String[] mItems = new String[NUMBER_ELEMENTS];
@@ -52,13 +50,8 @@
     @Override
     public void onResume() {
         super.onResume();
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                Intent intent = new Intent(TASKSWITCHING_INTENT);
-                sendBroadcast(intent);
-            }
+        mHandler.post(() -> {
+            getIntent().<RemoteCallback>getParcelableExtra("callback").sendResult(null);
         });
     }
 }
diff --git a/hostsidetests/ui/control/Android.mk b/hostsidetests/ui/control/Android.mk
index 3b4f8da..e35c4f0 100644
--- a/hostsidetests/ui/control/Android.mk
+++ b/hostsidetests/ui/control/Android.mk
@@ -31,6 +31,6 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/ui/control/AndroidManifest.xml b/hostsidetests/ui/control/AndroidManifest.xml
index 8102620..2b6b0dd 100644
--- a/hostsidetests/ui/control/AndroidManifest.xml
+++ b/hostsidetests/ui/control/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.taskswitching.control.cts">
+        package="android.taskswitching.control.cts"
+        android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java b/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java
index 6b99c20..1471550 100644
--- a/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java
+++ b/hostsidetests/ui/control/src/android/taskswitching/control/cts/TaskSwitchingDeviceTest.java
@@ -16,17 +16,11 @@
 
 package android.taskswitching.control.cts;
 
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.RemoteCallback;
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
-
 import com.android.compatibility.common.util.DeviceReportLog;
 import com.android.compatibility.common.util.MeasureRun;
 import com.android.compatibility.common.util.MeasureTime;
@@ -34,6 +28,11 @@
 import com.android.compatibility.common.util.ResultUnit;
 import com.android.compatibility.common.util.Stat;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
 /**
  * Device test which actually launches two apps sequentially and
  * measure time for switching.
@@ -41,32 +40,15 @@
  */
 public class TaskSwitchingDeviceTest extends CtsAndroidTestCase {
     private static final String REPORT_LOG_NAME = "CtsUiHostTestCases";
-    private static final String PKG_A = "android.taskswitching.appa";
-    private static final String PKG_B = "android.taskswitching.appb";
-    private static final String ACTIVITY_A = "AppAActivity";
-    private static final String ACTIVITY_B = "AppBActivity";
     private static final long TASK_SWITCHING_WAIT_TIME = 5;
-    private final AppBroadcastReceiver mReceiverA = new AppBroadcastReceiver();
-    private final AppBroadcastReceiver mReceiverB = new AppBroadcastReceiver();
+
+    private final Semaphore mSemaphore = new Semaphore(0);
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        getContext().registerReceiver(mReceiverA, new IntentFilter(PKG_A));
-        getContext().registerReceiver(mReceiverB, new IntentFilter(PKG_B));
 
-        startActivity(PKG_A, ACTIVITY_A);
-        assertTrue(mReceiverA.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
-
-        startActivity(PKG_B, ACTIVITY_B);
-        assertTrue(mReceiverB.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        getContext().unregisterReceiver(mReceiverA);
-        getContext().unregisterReceiver(mReceiverB);
-        super.tearDown();
+        startActivitiesABSequentially();
     }
 
     public void testMeasureTaskSwitching() throws Exception {
@@ -78,10 +60,7 @@
             @Override
             public void run(int i) throws Exception {
                 for (int j = 0; j < SWITCHING_PER_ONE_TRY; j++) {
-                    startActivity(PKG_A, ACTIVITY_A);
-                    assertTrue(mReceiverA.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
-                    startActivity(PKG_B, ACTIVITY_B);
-                    assertTrue(mReceiverB.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
+                    startActivitiesABSequentially();
                 }
             }
         });
@@ -94,24 +73,20 @@
         report.submit(getInstrumentation());
     }
 
-    private void startActivity(String packageName, String activityName) {
-        Context context = getContext();
-        Intent intent = new Intent();
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.setComponent(new ComponentName(packageName, packageName + "." + activityName));
-        context.startActivity(intent);
+    private void startActivitiesABSequentially()
+            throws InterruptedException, TimeoutException, ExecutionException {
+        startActivityAndWait('a');
+        startActivityAndWait('b');
     }
 
-    class AppBroadcastReceiver extends BroadcastReceiver {
-        private final Semaphore mSemaphore = new Semaphore(0);
-
-        public boolean waitForBroadcast(long timeoutInSec) throws InterruptedException {
-            return mSemaphore.tryAcquire(timeoutInSec, TimeUnit.SECONDS);
-        }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mSemaphore.release();
-        }
+    private void startActivityAndWait(char activityLetter)
+            throws InterruptedException, TimeoutException, ExecutionException {
+        getContext().startActivity(new Intent(Intent.ACTION_VIEW)
+                .setData(Uri.parse("https://foo.com/app" + activityLetter))
+                .addCategory(Intent.CATEGORY_DEFAULT)
+                .addCategory(Intent.CATEGORY_BROWSABLE)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                .putExtra("callback", new RemoteCallback(b -> mSemaphore.release())));
+        mSemaphore.tryAcquire(TASK_SWITCHING_WAIT_TIME, TimeUnit.SECONDS);
     }
 }
diff --git a/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java b/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java
index 03a581d..c45b021 100644
--- a/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java
+++ b/hostsidetests/ui/src/android/ui/cts/InstallTimeTest.java
@@ -16,6 +16,9 @@
 
 package android.ui.cts;
 
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.compatibility.common.util.MeasureRun;
 import com.android.compatibility.common.util.MeasureTime;
@@ -71,7 +74,17 @@
         super.tearDown();
     }
 
-    public void testInstallTime() throws Exception {
+    @AppModeInstant
+    public void testInstallTimeInstant() throws Exception {
+        testInstallTime(true);
+    }
+
+    @AppModeFull
+    public void testInstallTimeFull() throws Exception {
+        testInstallTime(false);
+    }
+
+    private void testInstallTime(boolean instant) throws Exception {
         String streamName = "test_install_time";
         MetricsReportLog report = new MetricsReportLog(mBuild, mAbi.getName(),
                 String.format("%s#%s", getClass().getName(), "testInstallTime"), REPORT_LOG_NAME,
@@ -87,7 +100,8 @@
             @Override
             public void run(int i) throws Exception {
                 File app = buildHelper.getTestFile(APK);
-                String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+                String[] options =
+                        {AbiUtils.createAbiFlag(mAbi.getName()), instant ? "--instant" : ""};
                 device.installPackage(app, false, options);
             }
         });
diff --git a/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java b/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java
index 814d4e1..9f2bd44 100644
--- a/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java
+++ b/hostsidetests/ui/src/android/ui/cts/TaskSwitchingTest.java
@@ -16,6 +16,9 @@
 
 package android.ui.cts;
 
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.compatibility.common.util.MetricsStore;
 import com.android.compatibility.common.util.ReportLog;
@@ -76,9 +79,13 @@
     protected void setUp() throws Exception {
         super.setUp();
         mDevice = getDevice();
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+    }
+
+    private void installPackages(boolean instant) throws Exception {
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
         for (int i = 0; i < PACKAGES.length; i++) {
+            String[] options = {AbiUtils.createAbiFlag(mAbi.getName()),
+                    instant && !PACKAGES[i].contains("control") ? "--instant" : ""};
             mDevice.uninstallPackage(PACKAGES[i]);
             File app = buildHelper.getTestFile(APKS[i]);
             mDevice.installPackage(app, false, options);
@@ -94,7 +101,19 @@
         super.tearDown();
     }
 
-    public void testTaskSwitching() throws Exception {
+    @AppModeInstant
+    public void testTaskSwitchingInstant() throws Exception {
+        installPackages(true);
+        doTestTaskSwitching();
+    }
+
+    @AppModeFull
+    public void testTaskSwitchingFull() throws Exception {
+        installPackages(false);
+        doTestTaskSwitching();
+    }
+
+    private void doTestTaskSwitching() throws Exception {
         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGES[0], RUNNER,
                 mDevice.getIDevice());
         LocalListener listener = new LocalListener();
diff --git a/hostsidetests/webkit/Android.mk b/hostsidetests/webkit/Android.mk
index 663a079..c3ee4f3 100644
--- a/hostsidetests/webkit/Android.mk
+++ b/hostsidetests/webkit/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_CTS_TEST_PACKAGE := android.webkit.hostside
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/hostsidetests/webkit/app/Android.mk b/hostsidetests/webkit/app/Android.mk
index fd2ee9a..2b0be1c 100644
--- a/hostsidetests/webkit/app/Android.mk
+++ b/hostsidetests/webkit/app/Android.mk
@@ -40,6 +40,6 @@
 LOCAL_DEX_PREOPT := false
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/webkit/app/AndroidManifest.xml b/hostsidetests/webkit/app/AndroidManifest.xml
index 108e837..cfd25d5 100644
--- a/hostsidetests/webkit/app/AndroidManifest.xml
+++ b/hostsidetests/webkit/app/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.webkit">
+    package="com.android.cts.webkit" android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.INTERNET" />
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index 852e4a2..692310b 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -18,6 +18,7 @@
 
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.net.http.SslError;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -27,9 +28,11 @@
 import android.util.Log;
 import android.webkit.CookieManager;
 import android.webkit.CookieSyncManager;
+import android.webkit.SslErrorHandler;
 import android.webkit.WebView;
 import android.webkit.cts.CtsTestServer;
 import android.webkit.cts.WebViewOnUiThread;
+import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
 import android.webkit.WebView;
 
 import com.android.compatibility.common.util.NullWebViewUtils;
@@ -67,7 +70,8 @@
 
     @UiThreadTest
     public void testCookieManagerBlockingUiThread() throws Throwable {
-        CtsTestServer server = new CtsTestServer(mActivity, false);
+        // Instant app can only have https connection.
+        CtsTestServer server = new CtsTestServer(mActivity, true);
         final String url = server.getCookieUrl("death.html");
 
         Thread background = new Thread(new Runnable() {
@@ -95,7 +99,15 @@
 
         // Now create WebView and test that setting the cookie beforehand really worked.
         mActivity.createAndAttachWebView();
+        WebView webView = mActivity.getWebView();
         WebViewOnUiThread onUiThread = new WebViewOnUiThread(this, mActivity.getWebView());
+        webView.setWebViewClient(new WaitForLoadedClient(onUiThread) {
+            @Override
+            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+                // Not intended to verify server certificate, ignore the error.
+                if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) handler.proceed();
+            }
+        });
         onUiThread.loadUrlAndWaitForCompletion(url);
         assertEquals("1|count=41", onUiThread.getTitle()); // outgoing cookie
         CookieManager cookieManager = CookieManager.getInstance();
diff --git a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
index a083e08..55ea6cf 100644
--- a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
+++ b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
@@ -34,6 +34,7 @@
         final Intent reportAlarmIntent = new Intent(ACTION_REPORT_ALARM_EXPIRED);
         reportAlarmIntent.putExtra(EXTRA_ALARM_COUNT, count);
         reportAlarmIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        reportAlarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         context.sendBroadcast(reportAlarmIntent);
     }
 }
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
index 7c6fc65..36acd82 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
@@ -59,7 +59,7 @@
     private static final String TEST_APP_PACKAGE = "android.alarmmanager.alarmtestapp.cts";
     private static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestAlarmScheduler";
 
-    private static final long DEFAULT_WAIT = 1_000;
+    private static final long DEFAULT_WAIT = 4_000;
     private static final long POLL_INTERVAL = 200;
 
     // Tweaked alarm manager constants to facilitate testing
@@ -136,6 +136,7 @@
         setAlarmIntent.putExtra(TestAlarmScheduler.EXTRA_TRIGGER_TIME, triggerMillis);
         setAlarmIntent.putExtra(TestAlarmScheduler.EXTRA_REPEAT_INTERVAL, interval);
         setAlarmIntent.putExtra(TestAlarmScheduler.EXTRA_ALLOW_WHILE_IDLE, allowWhileIdle);
+        setAlarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendBroadcast(setAlarmIntent);
     }
 
diff --git a/tests/JobScheduler/Android.mk b/tests/JobScheduler/Android.mk
index 622c06e..9cb148b 100755
--- a/tests/JobScheduler/Android.mk
+++ b/tests/JobScheduler/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_SRC_FILES += $(call all-java-files-under, JobTestApp/src)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 # Must match the package name in CtsTestCaseList.mk
 LOCAL_PACKAGE_NAME := CtsJobSchedulerTestCases
diff --git a/tests/JobScheduler/AndroidManifest.xml b/tests/JobScheduler/AndroidManifest.xml
index 4c9625d..f58cdbc 100755
--- a/tests/JobScheduler/AndroidManifest.xml
+++ b/tests/JobScheduler/AndroidManifest.xml
@@ -17,7 +17,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.jobscheduler.cts"
-    android:sharedUserId="android.jobscheduler.cts.shared.uid">
+    android:targetSandboxVersion="2">
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
diff --git a/tests/JobScheduler/AndroidTest.xml b/tests/JobScheduler/AndroidTest.xml
index d7a5988..4820aa2 100644
--- a/tests/JobScheduler/AndroidTest.xml
+++ b/tests/JobScheduler/AndroidTest.xml
@@ -19,8 +19,6 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsJobSchedulerTestCases.apk" />
-        <option name="test-file-name" value="CtsJobSchedulerJobPerm.apk" />
-        <option name="test-file-name" value="CtsJobSchedulerSharedUid.apk" />
         <option name="test-file-name" value="CtsJobTestApp.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/JobScheduler/jobperm/README.txt b/tests/JobScheduler/jobperm/README.txt
deleted file mode 100644
index f285815..0000000
--- a/tests/JobScheduler/jobperm/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This APK uses the same shared UID as CtsJobSchedulerTestCases. It has no code but exists for
-a shared-UID tests.
\ No newline at end of file
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
index e28675d..e03d4ae 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
@@ -129,6 +129,13 @@
         assertJobNotReady(BATTERY_JOB_ID);
     }
 
+    static void waitFor(long waitMillis) throws Exception {
+        final long deadline = SystemClock.uptimeMillis() + waitMillis;
+        do {
+            Thread.sleep(500L);
+        } while (SystemClock.uptimeMillis() < deadline);
+    }
+
     // --------------------------------------------------------------------------------------------
     // Positives - schedule jobs under conditions that require them to pass.
     // --------------------------------------------------------------------------------------------
@@ -157,6 +164,7 @@
      */
     public void testBatteryNotLowConstraintExecutes_withPower() throws Exception {
         setBatteryState(true, 100);
+        waitFor(2_000);
         verifyChargingState(true);
         verifyBatteryNotLowState(true);
 
@@ -176,6 +184,7 @@
      */
     public void testBatteryNotLowConstraintExecutes_withoutPower() throws Exception {
         setBatteryState(false, 100);
+        waitFor(2_000);
         verifyChargingState(false);
         verifyBatteryNotLowState(true);
 
@@ -238,6 +247,10 @@
      */
     public void testBatteryNotLowConstraintFails_withoutPower() throws Exception {
         setBatteryState(false, 15);
+        // setBatteryState() waited for the charging/not-charging state to formally settle,
+        // but battery level reporting lags behind that.  wait a moment to let that happen
+        // before proceeding.
+        waitFor(2_000);
         verifyChargingState(false);
         verifyBatteryNotLowState(false);
 
@@ -258,6 +271,7 @@
         kTestEnvironment.setExpectedWaitForRun();
         kTestEnvironment.setContinueAfterStart();
         setBatteryState(false, 50);
+        waitFor(2_000);
         verifyChargingState(false);
         verifyBatteryNotLowState(true);
         kTestEnvironment.setExpectedStopped();
@@ -269,6 +283,7 @@
         // And check that the job is stopped if battery goes low again.
         setBatteryState(false, 15);
         setBatteryState(false, 14);
+        waitFor(2_000);
         verifyChargingState(false);
         verifyBatteryNotLowState(false);
         assertTrue("Job with not low constraint did not stop when battery went low.",
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
index fe48950..4a0a24c 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
@@ -16,6 +16,10 @@
 
 package android.jobscheduler.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
diff --git a/tests/JobSchedulerSharedUid/Android.mk b/tests/JobSchedulerSharedUid/Android.mk
new file mode 100755
index 0000000..416c2e3
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ub-uiautomator android-support-test
+
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, JobSharedUidTestApp/src)
+LOCAL_SRC_FILES += $(call all-java-files-under, jobperm/src)
+LOCAL_SRC_FILES += $(call all-java-files-under, shareduid/src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_PACKAGE_NAME := CtsJobSchedulerSharedUidTestCases
+
+#LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/JobSchedulerSharedUid/AndroidManifest.xml b/tests/JobSchedulerSharedUid/AndroidManifest.xml
new file mode 100755
index 0000000..5cf9ce5
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.jobscheduler.cts.shareduidtests"
+    android:sharedUserId="android.jobscheduler.cts.shared.uid">
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <service android:name="android.jobscheduler.MockJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
+        <service android:name="android.jobscheduler.TriggerContentJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
+
+        <provider android:name="android.jobscheduler.DummyJobContentProvider"
+            android:authorities="android.jobscheduler.dummyprovider" android:multiprocess="false" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="JobScheduler shared-uid device-side tests"
+        android:targetPackage="android.jobscheduler.cts.shareduidtests" >
+    </instrumentation>
+</manifest>
diff --git a/tests/JobSchedulerSharedUid/AndroidTest.xml b/tests/JobSchedulerSharedUid/AndroidTest.xml
new file mode 100644
index 0000000..db88860
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS Job Scheduler shared-uid test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsJobSchedulerSharedUidTestCases.apk" />
+        <option name="test-file-name" value="CtsJobSchedulerJobPerm.apk" />
+        <option name="test-file-name" value="CtsJobSchedulerSharedUid.apk" />
+        <option name="test-file-name" value="CtsJobSharedUidTestApp.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.jobscheduler.cts.shareduidtests" />
+        <option name="runtime-hint" value="2m" />
+    </test>
+</configuration>
diff --git a/tests/JobScheduler/shareduid/Android.mk b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk
similarity index 83%
copy from tests/JobScheduler/shareduid/Android.mk
copy to tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk
index 98a9707..f3d36db 100644
--- a/tests/JobScheduler/shareduid/Android.mk
+++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 The Android Open Source Project
+# Copyright (C) 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -19,16 +19,13 @@
 # Don't include this package in any target.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    compatibility-device-util \
-
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_PACKAGE_NAME := CtsJobSchedulerSharedUid
+LOCAL_PACKAGE_NAME := CtsJobSharedUidTestApp
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/AndroidManifest.xml b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..7c030a9
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.jobscheduler.cts.shareduid.jobtestapp">
+
+    <!-- This application schedules jobs independently of the test instrumentation to make
+    it possible to test behaviour for different app states, whitelists and device idle modes -->
+    <application>
+        <service android:name=".TestJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" />
+        <activity android:name=".TestActivity"
+                  android:exported="true" />
+        <receiver android:name=".TestJobSchedulerReceiver"
+                  android:exported="true" />
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java
new file mode 100644
index 0000000..77107c2
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.jobscheduler.cts.jobtestapp;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Just a dummy activity to keep the test app process in the foreground state when desired.
+ */
+public class TestActivity extends Activity {
+    private static final String TAG = TestActivity.class.getSimpleName();
+    private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
+    private static final long DEFAULT_WAIT_DURATION = 30_000;
+
+    static final int FINISH_ACTIVITY_MSG = 1;
+    public static final String ACTION_FINISH_ACTIVITY = PACKAGE_NAME + ".action.FINISH_ACTIVITY";
+
+    Handler mFinishHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case FINISH_ACTIVITY_MSG:
+                    Log.d(TAG, "Finishing test activity: " + TestActivity.class.getCanonicalName());
+                    unregisterReceiver(mFinishReceiver);
+                    finish();
+            }
+        }
+    };
+
+    final BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mFinishHandler.removeMessages(FINISH_ACTIVITY_MSG);
+            mFinishHandler.sendEmptyMessage(FINISH_ACTIVITY_MSG);
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstance) {
+        Log.d(TAG, "Started test activity: " + TestActivity.class.getCanonicalName());
+        super.onCreate(savedInstance);
+        // automatically finish after 30 seconds.
+        mFinishHandler.sendEmptyMessageDelayed(FINISH_ACTIVITY_MSG, DEFAULT_WAIT_DURATION);
+        registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
+    }
+}
diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java
new file mode 100644
index 0000000..4ee0a03
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler.cts.jobtestapp;
+
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Schedules jobs for this package but does not, by itself, occupy a foreground uid state
+ * while doing so.
+ */
+public class TestJobSchedulerReceiver extends BroadcastReceiver {
+    private static final String TAG = TestJobSchedulerReceiver.class.getSimpleName();
+    private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
+
+    public static final String EXTRA_JOB_ID_KEY = PACKAGE_NAME + ".extra.JOB_ID";
+    public static final String EXTRA_ALLOW_IN_IDLE = PACKAGE_NAME + ".extra.ALLOW_IN_IDLE";
+    public static final String ACTION_SCHEDULE_JOB = PACKAGE_NAME + ".action.SCHEDULE_JOB";
+    public static final String ACTION_CANCEL_JOBS = PACKAGE_NAME + ".action.CANCEL_JOBS";
+    public static final int JOB_INITIAL_BACKOFF = 10_000;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final ComponentName jobServiceComponent = new ComponentName(context, TestJobService.class);
+        final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        switch (intent.getAction()) {
+            case ACTION_CANCEL_JOBS:
+                jobScheduler.cancelAll();
+                Log.d(TAG, "Cancelled all jobs for " + context.getPackageName());
+                break;
+            case ACTION_SCHEDULE_JOB:
+                final int jobId = intent.getIntExtra(EXTRA_JOB_ID_KEY, hashCode());
+                final boolean allowInIdle = intent.getBooleanExtra(EXTRA_ALLOW_IN_IDLE, false);
+                JobInfo.Builder jobBuilder = new JobInfo.Builder(jobId, jobServiceComponent)
+                        .setBackoffCriteria(JOB_INITIAL_BACKOFF, JobInfo.BACKOFF_POLICY_LINEAR)
+                        .setOverrideDeadline(0)
+                        .setImportantWhileForeground(allowInIdle);
+                final int result = jobScheduler.schedule(jobBuilder.build());
+                if (result != JobScheduler.RESULT_SUCCESS) {
+                    Log.e(TAG, "Could not schedule job " + jobId);
+                } else {
+                    Log.d(TAG, "Successfully scheduled job with id " + jobId);
+                }
+                break;
+            default:
+                Log.e(TAG, "Unknown action " + intent.getAction());
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobService.java b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobService.java
new file mode 100644
index 0000000..90a2ebf
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.jobscheduler.cts.jobtestapp;
+
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.content.Intent;
+import android.util.Log;
+
+public class TestJobService extends JobService {
+    private static final String TAG = TestJobService.class.getSimpleName();
+    private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
+    public static final String ACTION_JOB_STARTED = PACKAGE_NAME + ".action.JOB_STARTED";
+    public static final String ACTION_JOB_STOPPED = PACKAGE_NAME + ".action.JOB_STOPPED";
+    public static final String JOB_PARAMS_EXTRA_KEY = PACKAGE_NAME + ".extra.JOB_PARAMETERS";
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+        final Intent reportJobStartIntent = new Intent(ACTION_JOB_STARTED);
+        reportJobStartIntent.putExtra(JOB_PARAMS_EXTRA_KEY, params);
+        sendBroadcast(reportJobStartIntent);
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        Log.i(TAG, "Test job stopped executing: " + params.getJobId());
+        final Intent reportJobStopIntent = new Intent(ACTION_JOB_STOPPED);
+        reportJobStopIntent.putExtra(JOB_PARAMS_EXTRA_KEY, params);
+        sendBroadcast(reportJobStopIntent);
+        return true;
+    }
+}
diff --git a/tests/JobSchedulerSharedUid/assets/violet.jpg b/tests/JobSchedulerSharedUid/assets/violet.jpg
new file mode 100644
index 0000000..7785dfd
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/assets/violet.jpg
Binary files differ
diff --git a/tests/JobScheduler/jobperm/Android.mk b/tests/JobSchedulerSharedUid/jobperm/Android.mk
similarity index 94%
rename from tests/JobScheduler/jobperm/Android.mk
rename to tests/JobSchedulerSharedUid/jobperm/Android.mk
index af892d9..8be235f 100644
--- a/tests/JobScheduler/jobperm/Android.mk
+++ b/tests/JobSchedulerSharedUid/jobperm/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 The Android Open Source Project
+# Copyright (C) 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/tests/JobScheduler/jobperm/AndroidManifest.xml b/tests/JobSchedulerSharedUid/jobperm/AndroidManifest.xml
similarity index 88%
rename from tests/JobScheduler/jobperm/AndroidManifest.xml
rename to tests/JobSchedulerSharedUid/jobperm/AndroidManifest.xml
index 493c3e8..45e9cf0 100755
--- a/tests/JobScheduler/jobperm/AndroidManifest.xml
+++ b/tests/JobSchedulerSharedUid/jobperm/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2017 The Android Open Source Project
+  ~ Copyright (C) 2018 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.jobscheduler.cts.jobperm">
+          package="android.jobscheduler.cts.shareduid.jobperm">
 
     <!--
     An app that declares a permission that requires a matching signature to
@@ -32,7 +32,7 @@
         <!-- Need a way for another app to try to access the permission. So create a content
         provider which is enforced by the permission -->
         <provider android:name=".JobPermProvider"
-            android:authorities="android.jobscheduler.cts.jobperm.provider"
+            android:authorities="android.jobscheduler.cts.shareduid.jobperm.provider"
             android:exported="true">
             <path-permission
                 android:pathPrefix="/protected"
diff --git a/tests/JobSchedulerSharedUid/jobperm/README.txt b/tests/JobSchedulerSharedUid/jobperm/README.txt
new file mode 100644
index 0000000..14fa02e
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/jobperm/README.txt
@@ -0,0 +1,2 @@
+This APK uses the same shared UID as CtsJobSchedulerSharedUidTestCases. It has no code but exists for
+a shared-UID tests.
\ No newline at end of file
diff --git a/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java b/tests/JobSchedulerSharedUid/jobperm/src/android/jobscheduler/cts/shareduid/jobperm/JobPermProvider.java
similarity index 96%
rename from tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java
rename to tests/JobSchedulerSharedUid/jobperm/src/android/jobscheduler/cts/shareduid/jobperm/JobPermProvider.java
index 5b3bac7..5c6b4b2 100644
--- a/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java
+++ b/tests/JobSchedulerSharedUid/jobperm/src/android/jobscheduler/cts/shareduid/jobperm/JobPermProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.jobscheduler.cts.jobperm;
+package android.jobscheduler.cts.shareduid.jobperm;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/tests/JobScheduler/shareduid/Android.mk b/tests/JobSchedulerSharedUid/shareduid/Android.mk
similarity index 94%
rename from tests/JobScheduler/shareduid/Android.mk
rename to tests/JobSchedulerSharedUid/shareduid/Android.mk
index 98a9707..1376b4e 100644
--- a/tests/JobScheduler/shareduid/Android.mk
+++ b/tests/JobSchedulerSharedUid/shareduid/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 The Android Open Source Project
+# Copyright (C) 2018 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/tests/JobScheduler/shareduid/AndroidManifest.xml b/tests/JobSchedulerSharedUid/shareduid/AndroidManifest.xml
similarity index 94%
rename from tests/JobScheduler/shareduid/AndroidManifest.xml
rename to tests/JobSchedulerSharedUid/shareduid/AndroidManifest.xml
index 7b4bb56..97e5244 100755
--- a/tests/JobScheduler/shareduid/AndroidManifest.xml
+++ b/tests/JobSchedulerSharedUid/shareduid/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2017 The Android Open Source Project
+  ~ Copyright (C) 2018 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
diff --git a/tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java b/tests/JobSchedulerSharedUid/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
similarity index 91%
rename from tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
rename to tests/JobSchedulerSharedUid/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
index 229ed1f..3c2a265 100644
--- a/tests/JobScheduler/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
+++ b/tests/JobSchedulerSharedUid/shareduid/src/android/jobscheduler/cts/shareduid/Empty.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/JobSchedulerSharedUid/src/android/jobscheduler/DummyJobContentProvider.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/DummyJobContentProvider.java
new file mode 100644
index 0000000..9fa4c44
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/DummyJobContentProvider.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+
+/**
+ * Stub content provider used for generating content change reports
+ */
+public class DummyJobContentProvider extends ContentProvider {
+    private static final String DATABASE_NAME = "dummy.db";
+    private static final String NAME_VALUE_TABLE = "name_value";
+
+    private DatabaseHelper mDbHelper;
+    private static UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int MATCH_NAME_VALUE      = 1;
+
+    public static final String AUTHORITY = "android.jobscheduler.dummyprovider";
+    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+    public static final String _ID   = "_id";
+    public static final String NAME  = "name";
+    public static final String VALUE = "value";
+
+    static {
+        sMatcher.addURI(AUTHORITY, null, MATCH_NAME_VALUE);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#onCreate()
+     */
+    @Override
+    public boolean onCreate() {
+        mDbHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    private class DatabaseHelper extends SQLiteOpenHelper {
+        private static final int DATABASE_VERSION = 1;
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            // create an empty name_value table
+            db.execSQL("CREATE TABLE " + NAME_VALUE_TABLE + " (" + _ID + " INTEGER PRIMARY KEY,"
+                    + NAME + " TEXT," + VALUE + " TEXT"+ ");");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#insert(android.net.Uri,
+     * android.content.ContentValues)
+     */
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return null;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        db.insert(tbName, VALUE, values);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return uri;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#query(android.net.Uri,
+     * java.lang.String[], java.lang.String, java.lang.String[],
+     * java.lang.String)
+     */
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return null;
+        }
+        SQLiteDatabase db = mDbHelper.getReadableDatabase();
+        Cursor c = db.query(tbName, projection, selection, selectionArgs, null, null, sortOrder);
+        c.setNotificationUri(getContext().getContentResolver(), uri);
+        return c;
+    }
+
+    private String getTableName(Uri uri) {
+        switch (sMatcher.match(uri)) {
+            case MATCH_NAME_VALUE:
+                return NAME_VALUE_TABLE;
+            default:
+                throw new UnsupportedOperationException();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#update(android.net.Uri,
+     * android.content.ContentValues, java.lang.String, java.lang.String[])
+     */
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return 0;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        int count = db.update(tbName, values, selection, selectionArgs);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#delete(android.net.Uri,
+     * java.lang.String, java.lang.String[])
+     */
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return 0;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        int count = db.delete(tbName, selection, selectionArgs);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#getType(android.net.Uri)
+     */
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+}
diff --git a/tests/JobSchedulerSharedUid/src/android/jobscheduler/MockJobService.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/MockJobService.java
new file mode 100644
index 0000000..cb5a2da
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/MockJobService.java
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.JobWorkItem;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Process;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Handles callback from the framework {@link android.app.job.JobScheduler}. The behaviour of this
+ * class is configured through the static
+ * {@link TestEnvironment}.
+ */
+@TargetApi(21)
+public class MockJobService extends JobService {
+    private static final String TAG = "MockJobService";
+
+    /** Wait this long before timing out the test. */
+    private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+
+    private JobParameters mParams;
+
+    ArrayList<JobWorkItem> mReceivedWork = new ArrayList<>();
+
+    ArrayList<JobWorkItem> mPendingCompletions = new ArrayList<>();
+
+    private boolean mWaitingForStop;
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, "Destroying test service");
+        if (TestEnvironment.getTestEnvironment().getExpectedWork() != null) {
+            TestEnvironment.getTestEnvironment().notifyExecution(mParams, 0, 0, mReceivedWork,
+                    null);
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "Created test service.");
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+        mParams = params;
+
+        int permCheckRead = PackageManager.PERMISSION_DENIED;
+        int permCheckWrite = PackageManager.PERMISSION_DENIED;
+        ClipData clip = params.getClipData();
+        if (clip != null) {
+            permCheckRead = checkUriPermission(clip.getItemAt(0).getUri(), Process.myPid(),
+                    Process.myUid(), Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            permCheckWrite = checkUriPermission(clip.getItemAt(0).getUri(), Process.myPid(),
+                    Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+        }
+
+        TestWorkItem[] expectedWork = TestEnvironment.getTestEnvironment().getExpectedWork();
+        if (expectedWork != null) {
+            try {
+                if (!TestEnvironment.getTestEnvironment().awaitDoWork()) {
+                    TestEnvironment.getTestEnvironment().notifyExecution(params, permCheckRead,
+                            permCheckWrite, null, "Spent too long waiting to start executing work");
+                    return false;
+                }
+            } catch (InterruptedException e) {
+                TestEnvironment.getTestEnvironment().notifyExecution(params, permCheckRead,
+                        permCheckWrite, null, "Failed waiting for work: " + e);
+                return false;
+            }
+            JobWorkItem work;
+            int index = 0;
+            while ((work = params.dequeueWork()) != null) {
+                Log.i(TAG, "Received work #" + index + ": " + work.getIntent());
+                mReceivedWork.add(work);
+
+                int flags = 0;
+
+                if (index < expectedWork.length) {
+                    TestWorkItem expected = expectedWork[index];
+                    int grantFlags = work.getIntent().getFlags();
+                    if (expected.requireUrisGranted != null) {
+                        for (int ui = 0; ui < expected.requireUrisGranted.length; ui++) {
+                            if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_GRANTED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Expected read permission but not granted: "
+                                                    + expected.requireUrisGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                            if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_GRANTED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Expected write permission but not granted: "
+                                                    + expected.requireUrisGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+                    if (expected.requireUrisNotGranted != null) {
+                        // XXX note no delay here, current impl will have fully revoked the
+                        // permission by the time we return from completing the last work.
+                        for (int ui = 0; ui < expected.requireUrisNotGranted.length; ui++) {
+                            if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisNotGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_DENIED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Not expected read permission but granted: "
+                                                    + expected.requireUrisNotGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                            if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                                if (checkUriPermission(expected.requireUrisNotGranted[ui],
+                                        Process.myPid(), Process.myUid(),
+                                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+                                        != PackageManager.PERMISSION_DENIED) {
+                                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                            permCheckRead, permCheckWrite, null,
+                                            "Not expected write permission but granted: "
+                                                    + expected.requireUrisNotGranted[ui]
+                                                    + " @ #" + index);
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+
+                    flags = expected.flags;
+
+                    if ((flags & TestWorkItem.FLAG_WAIT_FOR_STOP) != 0) {
+                        Log.i(TAG, "Now waiting to stop");
+                        mWaitingForStop = true;
+                        TestEnvironment.getTestEnvironment().notifyWaitingForStop();
+                        return true;
+                    }
+
+                    if ((flags & TestWorkItem.FLAG_COMPLETE_NEXT) != 0) {
+                        if (!processNextPendingCompletion()) {
+                            TestEnvironment.getTestEnvironment().notifyExecution(params,
+                                    0, 0, null,
+                                    "Expected to complete next pending work but there was none: "
+                                            + " @ #" + index);
+                            return false;
+                        }
+                    }
+                }
+
+                if ((flags & TestWorkItem.FLAG_DELAY_COMPLETE_PUSH_BACK) != 0) {
+                    mPendingCompletions.add(work);
+                } else if ((flags & TestWorkItem.FLAG_DELAY_COMPLETE_PUSH_TOP) != 0) {
+                    mPendingCompletions.add(0, work);
+                } else {
+                    mParams.completeWork(work);
+                }
+
+                if (index < expectedWork.length) {
+                    TestWorkItem expected = expectedWork[index];
+                    if (expected.subitems != null) {
+                        final TestWorkItem[] sub = expected.subitems;
+                        final JobInfo ji = expected.jobInfo;
+                        final JobScheduler js = (JobScheduler) getSystemService(
+                                Context.JOB_SCHEDULER_SERVICE);
+                        for (int subi = 0; subi < sub.length; subi++) {
+                            js.enqueue(ji, new JobWorkItem(sub[subi].intent));
+                        }
+                    }
+                }
+
+                index++;
+            }
+
+            if (processNextPendingCompletion()) {
+                // We had some pending completions, clean them all out...
+                while (processNextPendingCompletion()) {
+                }
+                // ...and we need to do a final dequeue to complete the job, which should not
+                // return any remaining work.
+                if ((work = params.dequeueWork()) != null) {
+                    TestEnvironment.getTestEnvironment().notifyExecution(params,
+                            0, 0, null,
+                            "Expected no remaining work after dequeue pending, but got: " + work);
+                }
+            }
+
+            Log.i(TAG, "Done with all work at #" + index);
+            // We don't notifyExecution here because we want to make sure the job properly
+            // stops itself.
+            return true;
+        } else {
+            boolean continueAfterStart
+                    = TestEnvironment.getTestEnvironment().handleContinueAfterStart();
+            try {
+                if (!TestEnvironment.getTestEnvironment().awaitDoJob()) {
+                    TestEnvironment.getTestEnvironment().notifyExecution(params, permCheckRead,
+                            permCheckWrite, null, "Spent too long waiting to start job");
+                    return false;
+                }
+            } catch (InterruptedException e) {
+                TestEnvironment.getTestEnvironment().notifyExecution(params, permCheckRead,
+                        permCheckWrite, null, "Failed waiting to start job: " + e);
+                return false;
+            }
+            TestEnvironment.getTestEnvironment().notifyExecution(params, permCheckRead,
+                    permCheckWrite, null, null);
+            return continueAfterStart;
+        }
+    }
+
+    boolean processNextPendingCompletion() {
+        if (mPendingCompletions.size() <= 0) {
+            return false;
+        }
+
+        JobWorkItem next = mPendingCompletions.remove(0);
+        mParams.completeWork(next);
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        Log.i(TAG, "Received stop callback");
+        TestEnvironment.getTestEnvironment().notifyStopped();
+        return mWaitingForStop;
+    }
+
+    public static final class TestWorkItem {
+        /**
+         * Stop processing work for now, waiting for the service to be stopped.
+         */
+        public static final int FLAG_WAIT_FOR_STOP = 1<<0;
+        /**
+         * Don't complete this work now, instead push it on the back of the stack of
+         * pending completions.
+         */
+        public static final int FLAG_DELAY_COMPLETE_PUSH_BACK = 1<<1;
+        /**
+         * Don't complete this work now, instead insert to the top of the stack of
+         * pending completions.
+         */
+        public static final int FLAG_DELAY_COMPLETE_PUSH_TOP = 1<<2;
+        /**
+         * Complete next pending completion on the stack before completing this one.
+         */
+        public static final int FLAG_COMPLETE_NEXT = 1<<3;
+
+        public final Intent intent;
+        public final JobInfo jobInfo;
+        public final int flags;
+        public final int deliveryCount;
+        public final TestWorkItem[] subitems;
+        public final Uri[] requireUrisGranted;
+        public final Uri[] requireUrisNotGranted;
+
+        public TestWorkItem(Intent _intent) {
+            intent = _intent;
+            jobInfo = null;
+            flags = 0;
+            deliveryCount = 1;
+            subitems = null;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, int _flags) {
+            intent = _intent;
+            jobInfo = null;
+            flags = _flags;
+            deliveryCount = 1;
+            subitems = null;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, int _flags, int _deliveryCount) {
+            intent = _intent;
+            jobInfo = null;
+            flags = _flags;
+            deliveryCount = _deliveryCount;
+            subitems = null;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, JobInfo _jobInfo, TestWorkItem[] _subitems) {
+            intent = _intent;
+            jobInfo = _jobInfo;
+            flags = 0;
+            deliveryCount = 1;
+            subitems = _subitems;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, Uri[] _requireUrisGranted,
+                Uri[] _requireUrisNotGranted) {
+            intent = _intent;
+            jobInfo = null;
+            flags = 0;
+            deliveryCount = 1;
+            subitems = null;
+            requireUrisGranted = _requireUrisGranted;
+            requireUrisNotGranted = _requireUrisNotGranted;
+        }
+
+        @Override
+        public String toString() {
+            return "TestWorkItem { " + intent + " dc=" + deliveryCount + " }";
+        }
+    }
+
+    /**
+     * Configures the expected behaviour for each test. This object is shared across consecutive
+     * tests, so to clear state each test is responsible for calling
+     * {@link TestEnvironment#setUp()}.
+     */
+    public static final class TestEnvironment {
+
+        private static TestEnvironment kTestEnvironment;
+        //public static final int INVALID_JOB_ID = -1;
+
+        private CountDownLatch mLatch;
+        private CountDownLatch mWaitingForStopLatch;
+        private CountDownLatch mDoJobLatch;
+        private CountDownLatch mStoppedLatch;
+        private CountDownLatch mDoWorkLatch;
+        private TestWorkItem[] mExpectedWork;
+        private boolean mContinueAfterStart;
+        private JobParameters mExecutedJobParameters;
+        private int mExecutedPermCheckRead;
+        private int mExecutedPermCheckWrite;
+        private ArrayList<JobWorkItem> mExecutedReceivedWork;
+        private String mExecutedErrorMessage;
+
+        public static TestEnvironment getTestEnvironment() {
+            if (kTestEnvironment == null) {
+                kTestEnvironment = new TestEnvironment();
+            }
+            return kTestEnvironment;
+        }
+
+        public TestWorkItem[] getExpectedWork() {
+            return mExpectedWork;
+        }
+
+        public JobParameters getLastJobParameters() {
+            return mExecutedJobParameters;
+        }
+
+        public int getLastPermCheckRead() {
+            return mExecutedPermCheckRead;
+        }
+
+        public int getLastPermCheckWrite() {
+            return mExecutedPermCheckWrite;
+        }
+
+        public ArrayList<JobWorkItem> getLastReceivedWork() {
+            return mExecutedReceivedWork;
+        }
+
+        public String getLastErrorMessage() {
+            return mExecutedErrorMessage;
+        }
+
+        /**
+         * Block the test thread, waiting on the JobScheduler to execute some previously scheduled
+         * job on this service.
+         */
+        public boolean awaitExecution() throws InterruptedException {
+            return awaitExecution(DEFAULT_TIMEOUT_MILLIS);
+        }
+
+        public boolean awaitExecution(long timeoutMillis) throws InterruptedException {
+            final boolean executed = mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            if (getLastErrorMessage() != null) {
+                Assert.fail(getLastErrorMessage());
+            }
+            return executed;
+        }
+
+        /**
+         * Block the test thread, expecting to timeout but still listening to ensure that no jobs
+         * land in the interim.
+         * @return True if the latch timed out waiting on an execution.
+         */
+        public boolean awaitTimeout() throws InterruptedException {
+            return awaitTimeout(DEFAULT_TIMEOUT_MILLIS);
+        }
+
+        public boolean awaitTimeout(long timeoutMillis) throws InterruptedException {
+            return !mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+        }
+
+        public boolean awaitWaitingForStop() throws InterruptedException {
+            return mWaitingForStopLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        public boolean awaitDoWork() throws InterruptedException {
+            return mDoWorkLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        public boolean awaitDoJob() throws InterruptedException {
+            if (mDoJobLatch == null) {
+                return true;
+            }
+            return mDoJobLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        public boolean awaitStopped() throws InterruptedException {
+            return mStoppedLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        private void notifyExecution(JobParameters params, int permCheckRead, int permCheckWrite,
+                ArrayList<JobWorkItem> receivedWork, String errorMsg) {
+            //Log.d(TAG, "Job executed:" + params.getJobId());
+            mExecutedJobParameters = params;
+            mExecutedPermCheckRead = permCheckRead;
+            mExecutedPermCheckWrite = permCheckWrite;
+            mExecutedReceivedWork = receivedWork;
+            mExecutedErrorMessage = errorMsg;
+            mLatch.countDown();
+        }
+
+        private void notifyWaitingForStop() {
+            mWaitingForStopLatch.countDown();
+        }
+
+        private void notifyStopped() {
+            if (mStoppedLatch != null) {
+                mStoppedLatch.countDown();
+            }
+        }
+
+        public void setExpectedExecutions(int numExecutions) {
+            // For no executions expected, set count to 1 so we can still block for the timeout.
+            if (numExecutions == 0) {
+                mLatch = new CountDownLatch(1);
+            } else {
+                mLatch = new CountDownLatch(numExecutions);
+            }
+            mWaitingForStopLatch = null;
+            mDoJobLatch = null;
+            mStoppedLatch = null;
+            mDoWorkLatch = null;
+            mExpectedWork = null;
+            mContinueAfterStart = false;
+        }
+
+        public void setExpectedWaitForStop() {
+            mWaitingForStopLatch = new CountDownLatch(1);
+        }
+
+        public void setExpectedWork(TestWorkItem[] work) {
+            mExpectedWork = work;
+            mDoWorkLatch = new CountDownLatch(1);
+        }
+
+        public void setExpectedStopped() {
+            mStoppedLatch = new CountDownLatch(1);
+        }
+
+        public void readyToWork() {
+            mDoWorkLatch.countDown();
+        }
+
+        public void setExpectedWaitForRun() {
+            mDoJobLatch = new CountDownLatch(1);
+        }
+
+        public void readyToRun() {
+            mDoJobLatch.countDown();
+        }
+
+        public void setContinueAfterStart() {
+            mContinueAfterStart = true;
+        }
+
+        public boolean handleContinueAfterStart() {
+            boolean res = mContinueAfterStart;
+            mContinueAfterStart = false;
+            return res;
+        }
+
+        /** Called in each testCase#setup */
+        public void setUp() {
+            mLatch = null;
+            mExecutedJobParameters = null;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/tests/JobSchedulerSharedUid/src/android/jobscheduler/TriggerContentJobService.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/TriggerContentJobService.java
new file mode 100644
index 0000000..0428110
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/TriggerContentJobService.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Handles callback from the framework {@link android.app.job.JobScheduler}. The behaviour of this
+ * class is configured through the static
+ * {@link TestEnvironment}.
+ */
+@TargetApi(21)
+public class TriggerContentJobService extends JobService {
+    private static final String TAG = "TriggerContentJobService";
+
+    /** Wait this long before timing out the test. */
+    private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+
+    /** How long to delay before rescheduling the job each time we repeat. */
+    private static final long REPEAT_INTERVAL = 1000L; // 1 second.
+
+    JobInfo mRunningJobInfo;
+    JobParameters mRunningParams;
+
+    final Handler mHandler = new Handler();
+    final Runnable mWorkerReschedule = new Runnable() {
+        @Override public void run() {
+            scheduleJob(TriggerContentJobService.this, mRunningJobInfo);
+            jobFinished(mRunningParams, false);
+        }
+    };
+    final Runnable mWorkerFinishTrue = new Runnable() {
+        @Override public void run() {
+            jobFinished(mRunningParams, true);
+        }
+    };
+
+    public static void scheduleJob(Context context, JobInfo jobInfo) {
+        JobScheduler js = context.getSystemService(JobScheduler.class);
+        js.schedule(jobInfo);
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.e(TAG, "Created test service.");
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+
+        int mode = TestEnvironment.getTestEnvironment().getMode();
+        mRunningJobInfo = TestEnvironment.getTestEnvironment().getModeJobInfo();
+        TestEnvironment.getTestEnvironment().setMode(TestEnvironment.MODE_ONESHOT, null);
+        TestEnvironment.getTestEnvironment().notifyExecution(params);
+
+        if (mode == TestEnvironment.MODE_ONE_REPEAT_RESCHEDULE) {
+            mRunningParams = params;
+            mHandler.postDelayed(mWorkerReschedule, REPEAT_INTERVAL);
+            return true;
+        } else if (mode == TestEnvironment.MODE_ONE_REPEAT_FINISH_TRUE) {
+            mRunningParams = params;
+            mHandler.postDelayed(mWorkerFinishTrue, REPEAT_INTERVAL);
+            return true;
+        } else {
+            return false;  // No work to do.
+        }
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        return false;
+    }
+
+    /**
+     * Configures the expected behaviour for each test. This object is shared across consecutive
+     * tests, so to clear state each test is responsible for calling
+     * {@link TestEnvironment#setUp()}.
+     */
+    public static final class TestEnvironment {
+
+        private static TestEnvironment kTestEnvironment;
+        //public static final int INVALID_JOB_ID = -1;
+
+        private CountDownLatch mLatch;
+        private JobParameters mExecutedJobParameters;
+        private int mMode;
+        private JobInfo mModeJobInfo;
+
+        public static final int MODE_ONESHOT = 0;
+        public static final int MODE_ONE_REPEAT_RESCHEDULE = 1;
+        public static final int MODE_ONE_REPEAT_FINISH_TRUE = 2;
+
+        public static TestEnvironment getTestEnvironment() {
+            if (kTestEnvironment == null) {
+                kTestEnvironment = new TestEnvironment();
+            }
+            return kTestEnvironment;
+        }
+
+        public JobParameters getLastJobParameters() {
+            return mExecutedJobParameters;
+        }
+
+        /**
+         * Block the test thread, waiting on the JobScheduler to execute some previously scheduled
+         * job on this service.
+         */
+        public boolean awaitExecution() throws InterruptedException {
+            final boolean executed = mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            return executed;
+        }
+
+        public void setMode(int mode, JobInfo jobInfo) {
+            synchronized (this) {
+                mMode = mode;
+                mModeJobInfo = jobInfo;
+            }
+        }
+
+        public int getMode() {
+            synchronized (this) {
+                return mMode;
+            }
+        }
+
+        public JobInfo getModeJobInfo() {
+            synchronized (this) {
+                return mModeJobInfo;
+            }
+        }
+
+        /**
+         * Block the test thread, expecting to timeout but still listening to ensure that no jobs
+         * land in the interim.
+         * @return True if the latch timed out waiting on an execution.
+         */
+        public boolean awaitTimeout() throws InterruptedException {
+            return !mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        private void notifyExecution(JobParameters params) {
+            Log.d(TAG, "Job executed:" + params.getJobId());
+            mExecutedJobParameters = params;
+            mLatch.countDown();
+        }
+
+        public void setExpectedExecutions(int numExecutions) {
+            // For no executions expected, set count to 1 so we can still block for the timeout.
+            if (numExecutions == 0) {
+                mLatch = new CountDownLatch(1);
+            } else {
+                mLatch = new CountDownLatch(numExecutions);
+            }
+        }
+
+        /** Called in each testCase#setup */
+        public void setUp() {
+            mLatch = null;
+            mExecutedJobParameters = null;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ClipDataJobTest.java
similarity index 98%
rename from tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java
rename to tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ClipDataJobTest.java
index 03d941e..aa19a9a 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ClipDataJobTest.java
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ClipDataJobTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.jobscheduler.cts;
+package android.jobscheduler.cts.shareduidtests;
 
 
 import android.annotation.TargetApi;
diff --git a/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ConstraintTest.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ConstraintTest.java
new file mode 100644
index 0000000..fcdb593
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/ConstraintTest.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.jobscheduler.cts.shareduidtests;
+
+import android.annotation.TargetApi;
+import android.app.Instrumentation;
+import android.app.job.JobScheduler;
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.jobscheduler.MockJobService;
+import android.jobscheduler.TriggerContentJobService;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import java.io.IOException;
+
+/**
+ * Common functionality from which the other test case classes derive.
+ */
+@TargetApi(21)
+public abstract class ConstraintTest extends InstrumentationTestCase {
+    /** Force the scheduler to consider the device to be on stable charging. */
+    private static final Intent EXPEDITE_STABLE_CHARGING =
+            new Intent("com.android.server.task.controllers.BatteryController.ACTION_CHARGING_STABLE");
+
+    /** Environment that notifies of JobScheduler callbacks. */
+    static MockJobService.TestEnvironment kTestEnvironment =
+            MockJobService.TestEnvironment.getTestEnvironment();
+    static TriggerContentJobService.TestEnvironment kTriggerTestEnvironment =
+            TriggerContentJobService.TestEnvironment.getTestEnvironment();
+    /** Handle for the service which receives the execution callbacks from the JobScheduler. */
+    static ComponentName kJobServiceComponent;
+    static ComponentName kTriggerContentServiceComponent;
+    JobScheduler mJobScheduler;
+
+    Context mContext;
+
+    static final String MY_PACKAGE = "android.jobscheduler.cts.shareduidtests";
+
+    static final String JOBPERM_PACKAGE = "android.jobscheduler.cts.shareduid.jobperm";
+    static final String JOBPERM_AUTHORITY = "android.jobscheduler.cts.shareduid.jobperm.provider";
+    static final String JOBPERM_PERM = "android.jobscheduler.cts.jobperm.perm";
+
+    Uri mFirstUri;
+    Bundle mFirstUriBundle;
+    Uri mSecondUri;
+    Bundle mSecondUriBundle;
+    ClipData mFirstClipData;
+    ClipData mSecondClipData;
+
+    boolean mStorageStateChanged;
+
+    @Override
+    public void injectInstrumentation(Instrumentation instrumentation) {
+        super.injectInstrumentation(instrumentation);
+        mContext = instrumentation.getContext();
+        kJobServiceComponent = new ComponentName(getContext(), MockJobService.class);
+        kTriggerContentServiceComponent = new ComponentName(getContext(),
+                TriggerContentJobService.class);
+        mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        mFirstUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/foo");
+        mFirstUriBundle = new Bundle();
+        mFirstUriBundle.putParcelable("uri", mFirstUri);
+        mSecondUri = Uri.parse("content://" + JOBPERM_AUTHORITY + "/protected/bar");
+        mSecondUriBundle = new Bundle();
+        mSecondUriBundle.putParcelable("uri", mSecondUri);
+        mFirstClipData = new ClipData("JobPerm1", new String[] { "application/*" },
+                new ClipData.Item(mFirstUri));
+        mSecondClipData = new ClipData("JobPerm2", new String[] { "application/*" },
+                new ClipData.Item(mSecondUri));
+        try {
+            SystemUtil.runShellCommand(getInstrumentation(), "cmd activity set-inactive "
+                    + mContext.getPackageName() + " false");
+        } catch (IOException e) {
+            Log.w("ConstraintTest", "Failed setting inactive false", e);
+        }
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        kTestEnvironment.setUp();
+        kTriggerTestEnvironment.setUp();
+        mJobScheduler.cancelAll();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (mStorageStateChanged) {
+            // Put storage service back in to normal operation.
+            SystemUtil.runShellCommand(getInstrumentation(), "cmd devicestoragemonitor reset");
+            mStorageStateChanged = false;
+        }
+    }
+
+    /**
+     * The scheduler will usually only flush its queue of unexpired jobs when the device is
+     * considered to be on stable power - that is, plugged in for a period of 2 minutes.
+     * Rather than wait for this to happen, we cheat and send this broadcast instead.
+     */
+    protected void sendExpediteStableChargingBroadcast() {
+        getContext().sendBroadcast(EXPEDITE_STABLE_CHARGING);
+    }
+
+    public void assertHasUriPermission(Uri uri, int grantFlags) {
+        if ((grantFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+            assertEquals(PackageManager.PERMISSION_GRANTED,
+                    getContext().checkUriPermission(uri, Process.myPid(),
+                            Process.myUid(), Intent.FLAG_GRANT_READ_URI_PERMISSION));
+        }
+        if ((grantFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+            assertEquals(PackageManager.PERMISSION_GRANTED,
+                    getContext().checkUriPermission(uri, Process.myPid(),
+                            Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
+        }
+    }
+
+    void waitPermissionRevoke(Uri uri, int access, long timeout) {
+        long startTime = SystemClock.elapsedRealtime();
+        while (getContext().checkUriPermission(uri, Process.myPid(), Process.myUid(), access)
+                != PackageManager.PERMISSION_DENIED) {
+            try {
+                Thread.sleep(50);
+            } catch (InterruptedException e) {
+            }
+            if ((SystemClock.elapsedRealtime()-startTime) >= timeout) {
+                fail("Timed out waiting for permission revoke");
+            }
+        }
+    }
+
+    // Note we are just using storage state as a way to control when the job gets executed.
+    void setStorageState(boolean low) throws Exception {
+        mStorageStateChanged = true;
+        String res;
+        if (low) {
+            res = SystemUtil.runShellCommand(getInstrumentation(),
+                    "cmd devicestoragemonitor force-low -f");
+        } else {
+            res = SystemUtil.runShellCommand(getInstrumentation(),
+                    "cmd devicestoragemonitor force-not-low -f");
+        }
+        int seq = Integer.parseInt(res.trim());
+        long startTime = SystemClock.elapsedRealtime();
+
+        // Wait for the storage update to be processed by job scheduler before proceeding.
+        int curSeq;
+        do {
+            curSeq = Integer.parseInt(SystemUtil.runShellCommand(getInstrumentation(),
+                    "cmd jobscheduler get-storage-seq").trim());
+            if (curSeq == seq) {
+                return;
+            }
+        } while ((SystemClock.elapsedRealtime()-startTime) < 1000);
+
+        fail("Timed out waiting for job scheduler: expected seq=" + seq + ", cur=" + curSeq);
+    }
+
+    String getJobState(int jobId) throws Exception {
+        return SystemUtil.runShellCommand(getInstrumentation(),
+                "cmd jobscheduler get-job-state " + kJobServiceComponent.getPackageName()
+                        + " " + jobId).trim();
+    }
+
+    void assertJobReady(int jobId) throws Exception {
+        String state = getJobState(jobId);
+        assertTrue("Job unexpectedly not ready, in state: " + state, state.contains("ready"));
+    }
+
+    void assertJobWaiting(int jobId) throws Exception {
+        String state = getJobState(jobId);
+        assertTrue("Job unexpectedly not waiting, in state: " + state, state.contains("waiting"));
+    }
+
+    void assertJobNotReady(int jobId) throws Exception {
+        String state = getJobState(jobId);
+        assertTrue("Job unexpectedly ready, in state: " + state, !state.contains("ready"));
+    }
+}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/EnqueueJobWorkTest.java
similarity index 99%
rename from tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java
rename to tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/EnqueueJobWorkTest.java
index 604ccce..cadf73a 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/EnqueueJobWorkTest.java
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/EnqueueJobWorkTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.jobscheduler.cts;
+package android.jobscheduler.cts.shareduidtests;
 
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/SharedUidTest.java b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/SharedUidTest.java
similarity index 96%
rename from tests/JobScheduler/src/android/jobscheduler/cts/SharedUidTest.java
rename to tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/SharedUidTest.java
index 382828f..9ee2aee 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/SharedUidTest.java
+++ b/tests/JobSchedulerSharedUid/src/android/jobscheduler/cts/shareduidtests/SharedUidTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.jobscheduler.cts;
+package android.jobscheduler.cts.shareduidtests;
 
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index 8c87d78..0cf2c19 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -58,6 +58,8 @@
                 getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
         mTargetContext = getInstrumentation().getTargetContext();
         mHandler = new Handler(mTargetContext.getMainLooper());
+        // In case the test runner started a UiAutomation, destroy it to start with a clean slate.
+        getInstrumentation().getUiAutomation().destroy();
         ServiceControlUtils.turnAccessibilityOff(getInstrumentation());
     }
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
index 115eb5f..cd84fb9 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
@@ -249,8 +249,12 @@
         }
 
         // Scroll down one line
-        final float oneLineDownY = locationsBeforeScroll[0].bottom;
-        getInstrumentation().runOnMainSync(() -> editText.scrollTo(0, (int) oneLineDownY + 1));
+        getInstrumentation().runOnMainSync(() -> {
+            int[] viewPosition = new int[2];
+            editText.getLocationOnScreen(viewPosition);
+            final int oneLineDownY = (int) locationsBeforeScroll[0].bottom - viewPosition[1];
+            editText.scrollTo(0, oneLineDownY + 1);
+        });
 
         assertTrue("Refresh failed", text.refreshWithExtraData(
                 EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY, getTextArgs));
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index 2e89f06..25b7762 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -86,6 +86,7 @@
     PointF mCurrentZoomCenter = null;
     PointF mTapLocation;
     PointF mTapLocation2;
+    float mPan;
     private boolean mHasTouchscreen;
     private boolean mOriginalIsMagnificationEnabled;
 
@@ -127,6 +128,7 @@
             view.getLocationOnScreen(xy);
             mTapLocation = new PointF(xy[0] + view.getWidth() / 2, xy[1] + view.getHeight() / 2);
             mTapLocation2 = add(mTapLocation, 31, 29);
+            mPan = view.getWidth() / 4;
         });
     }
 
@@ -179,17 +181,15 @@
         if (!mHasTouchscreen) return;
         assertFalse(isZoomed());
 
-        float pan = Math.min(mTapLocation.x, mTapLocation2.x) / 2;
-
         setZoomByTripleTapping(true);
         PointF oldCenter = mCurrentZoomCenter;
 
         dispatch(
-                swipe(mTapLocation, add(mTapLocation, -pan, 0)),
-                swipe(mTapLocation2, add(mTapLocation2, -pan, 0)));
+                swipe(mTapLocation, add(mTapLocation, -mPan, 0)),
+                swipe(mTapLocation2, add(mTapLocation2, -mPan, 0)));
 
         waitOn(mZoomLock,
-                () -> (mCurrentZoomCenter.x - oldCenter.x >= pan / mCurrentScale * 0.9));
+                () -> (mCurrentZoomCenter.x - oldCenter.x >= mPan / mCurrentScale * 0.9));
 
         setZoomByTripleTapping(false);
     }
@@ -204,12 +204,11 @@
     private void tripleTapAndDragViewport() {
         StrokeDescription down = tripleTapAndHold();
 
-        float pan = mTapLocation.x / 2;
         PointF oldCenter = mCurrentZoomCenter;
 
-        StrokeDescription drag = drag(down, add(lastPointOf(down), pan, 0f));
+        StrokeDescription drag = drag(down, add(lastPointOf(down), mPan, 0f));
         dispatch(drag);
-        waitOn(mZoomLock, () -> distance(mCurrentZoomCenter, oldCenter) >= pan / 5);
+        waitOn(mZoomLock, () -> distance(mCurrentZoomCenter, oldCenter) >= mPan / 5);
         assertTrue(isZoomed());
         assertNoTouchInputPropagated();
 
diff --git a/tests/app/src/android/app/cts/DisplayTest.java b/tests/app/src/android/app/cts/DisplayTest.java
index 6d7fdeb..154f41f 100644
--- a/tests/app/src/android/app/cts/DisplayTest.java
+++ b/tests/app/src/android/app/cts/DisplayTest.java
@@ -19,6 +19,7 @@
 import android.app.Instrumentation;
 import android.app.stubs.DisplayTestActivity;
 import android.app.stubs.OrientationTestUtils;
+import android.graphics.Point;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.Display;
 
@@ -51,32 +52,36 @@
         final Display origDisplay = mActivity.getDisplay();
 
         // Capture the originally reported width and heights
-        final int origWidth = origDisplay.getWidth();
-        final int origHeight = origDisplay.getHeight();
+        final Point origSize = new Point();
+        origDisplay.getSize(origSize);
 
         // Change orientation
         mActivity.configurationChangeObserver.startObserving();
         OrientationTestUtils.switchOrientation(mActivity);
         mActivity.configurationChangeObserver.await();
 
+        final Point newOrigSize = new Point();
+        origDisplay.getSize(newOrigSize);
+
         // Get a {@link Display} instance after rotation.
         final Display updatedDisplay = mActivity.getDisplay();
+        final Point updatedSize = new Point();
+        updatedDisplay.getSize(updatedSize);
 
-        // For square sreens the following assertions do not make sense and will always fail.
-        if (origWidth != origHeight) {
+        // For square screens the following assertions do not make sense and will always fail.
+        if (origSize.x != origSize.y) {
             // Ensure that the width and height of the original instance no longer are the same. Note
             // that this will be false if the device width and height are identical.
-            assertFalse("width from original display instance should have changed",
-                    origWidth == origDisplay.getWidth());
-            assertFalse("height from original display instance should have changed",
-                    origHeight == origDisplay.getHeight());
+            // Note there are cases where width and height may not all be updated, such as on docked
+            // devices where the app is letterboxed. However at least one dimension needs to be
+            // updated.
+            assertFalse("size from original display instance should have changed",
+                    origSize.equals(newOrigSize));
         }
 
         // Ensure that the width and height of the original instance have been updated to match the
         // values that would be found in a new instance.
-        assertTrue("width from original display instance should match current",
-                origDisplay.getWidth() == updatedDisplay.getWidth());
-        assertTrue("height from original display instance should match current",
-                origDisplay.getHeight() == updatedDisplay.getHeight());
+        assertTrue("size from original display instance should match current",
+                newOrigSize.equals(updatedSize));
     }
 }
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
index 9ac86e1..3549145 100644
--- a/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -18,6 +18,7 @@
 
 import android.app.Notification;
 import android.app.Notification.Action.Builder;
+import android.app.Notification.MessagingStyle;
 import android.app.Notification.MessagingStyle.Message;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -255,6 +256,15 @@
         assertEquals(Notification.GROUP_ALERT_SUMMARY, mNotification.getGroupAlertBehavior());
     }
 
+    public void testBuilder_getStyle() {
+        MessagingStyle ms = new MessagingStyle(new Person.Builder().setName("Test name").build());
+        Notification.Builder builder = new Notification.Builder(mContext, CHANNEL.getId());
+
+        builder.setStyle(ms);
+
+        assertEquals(ms, builder.getStyle());
+    }
+
     public void testActionBuilder() {
         final Intent intent = new Intent();
         final PendingIntent actionIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
@@ -400,6 +410,26 @@
         assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION));
     }
 
+    public void testMessagingStyle_getUser() {
+        Person user = new Person.Builder().setName("Test name").build();
+
+        MessagingStyle messagingStyle = new MessagingStyle(user);
+
+        assertEquals(user, messagingStyle.getUser());
+    }
+
+    public void testMessage() {
+        Person sender = new Person.Builder().setName("Test name").build();
+        String text = "Test message";
+        long timestamp = 400;
+
+        Message message = new Message(text, timestamp, sender);
+
+        assertEquals(text, message.getText());
+        assertEquals(timestamp, message.getTimestamp());
+        assertEquals(sender, message.getSenderPerson());
+    }
+
     public void testToString() {
         mNotification = new Notification();
         assertNotNull(mNotification.toString());
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
index b27ad83..1eab92d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
@@ -60,6 +60,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Test that uses {@link LoginActivity} to test {@link FillEventHistory}.
@@ -108,8 +109,8 @@
         mActivity.onUsername(View::requestFocus);
 
         // Authenticate
-        mUiBot.selectDataset("authentication");
         sReplier.getNextFillRequest();
+        mUiBot.selectDataset("authentication");
         mActivity.assertAutoFilled();
 
         // Verify fill selection
@@ -145,8 +146,8 @@
         mActivity.onUsername(View::requestFocus);
 
         // Authenticate
-        mUiBot.selectDataset("authentication");
         sReplier.getNextFillRequest();
+        mUiBot.selectDataset("authentication");
         mUiBot.assertDatasets("dataset");
 
         // Verify fill selection
@@ -177,8 +178,8 @@
         // Trigger autofill on username
         mActivity.onUsername(View::requestFocus);
         waitUntilConnected();
-        mUiBot.selectDataset("dataset1");
         sReplier.getNextFillRequest();
+        mUiBot.selectDataset("dataset1");
         mActivity.assertAutoFilled();
 
         {
@@ -213,8 +214,8 @@
 
         // Trigger autofill on password
         mActivity.onPassword(View::requestFocus);
-        mUiBot.selectDataset("dataset3");
         sReplier.getNextFillRequest();
+        mUiBot.selectDataset("dataset3");
         mActivity.assertAutoFilled();
 
         {
@@ -412,8 +413,12 @@
 
         // Now switch back to A...
         mUiBot.pressBack(); // dismiss autofill
-        mUiBot.pressBack(); // dismiss keyboard
-        mUiBot.pressBack(); // dismiss task
+        mUiBot.pressBack(); // dismiss keyboard (or task, if there was no keyboard)
+        final AtomicBoolean focusOnA = new AtomicBoolean();
+        mActivity.syncRunOnUiThread(() -> focusOnA.set(mActivity.hasWindowFocus()));
+        if (!focusOnA.get()) {
+            mUiBot.pressBack(); // dismiss task, if the last pressBack dismissed only the keyboard
+        }
         mUiBot.assertShownByRelativeId(ID_USERNAME);
         assertWithMessage("root window has no focus")
                 .that(mActivity.getWindow().getDecorView().hasWindowFocus()).isTrue();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index fa8fa1b..c476c7c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2499,8 +2499,7 @@
         waitUntilConnected();
         sReplier.getNextFillRequest().cancellationSignal.setOnCancelListener(listener);
 
-        // AssertResults
-        waitUntilDisconnected();
+        // Assert results
         listener.assertOnCancelCalled();
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivityTest.java
index 92fa94b..b3257f0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PreSimpleSaveActivityTest.java
@@ -38,6 +38,7 @@
 import android.view.View;
 import android.widget.RemoteViews;
 
+import org.junit.After;
 import org.junit.Rule;
 
 import java.util.regex.Pattern;
@@ -59,6 +60,11 @@
         mActivity = mActivityRule.launchActivity(intent);
     }
 
+    @After
+    public void finishSimpleSaveActivity() {
+        SimpleSaveActivity.finishIt(mUiBot);
+    }
+
     @Override
     protected void saveUiRestoredAfterTappingLinkTest(PostSaveLinkTappedAction type)
             throws Exception {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
index cbb8523..a9924f4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivity.java
@@ -46,10 +46,18 @@
     private boolean mAutoCommit = true;
     private boolean mClearFieldsOnSubmit = false;
 
-    public static SimpleSaveActivity getInstance() {
+    static SimpleSaveActivity getInstance() {
         return sInstance;
     }
 
+    static void finishIt(UiBot uiBot) {
+        if (sInstance != null) {
+            Log.d(TAG, "So long and thanks for all the fish!");
+            sInstance.finish();
+            uiBot.assertGoneByRelativeId(ID_LABEL, Timeouts.ACTIVITY_RESURRECTION);
+        }
+    }
+
     public SimpleSaveActivity() {
         sInstance = this;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index 82632f2..eb59da4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -32,6 +32,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
 import android.autofillservice.cts.SimpleSaveActivity.FillExpectation;
@@ -191,6 +193,7 @@
 
     @Test
     public void testSave_afterRotation() throws Exception {
+        assumeTrue("Rotation is supported", Helper.isRotationSupported(mContext));
         mUiBot.setScreenOrientation(UiBot.PORTRAIT);
         try {
             saveTest(true);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
index ae12356..d59d1a5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
@@ -29,7 +29,9 @@
     /**
      * Timeout until framework unbinds from a service.
      */
-    static final Timeout IDLE_UNBIND_TIMEOUT = new Timeout("IDLE_UNBIND_TIMEOUT", 5000, 2F, 10000);
+    // TODO: must be higher than RemoteFillService.TIMEOUT_IDLE_BIND_MILLIS, so we should use a
+    // @hidden @Testing constants instead...
+    static final Timeout IDLE_UNBIND_TIMEOUT = new Timeout("IDLE_UNBIND_TIMEOUT", 10000, 2F, 10000);
 
     /**
      * Timeout to get the expected number of fill events.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
index ef54c78..a8da1a3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
@@ -15,6 +15,8 @@
  */
 package android.autofillservice.cts;
 
+import static android.autofillservice.cts.Timeouts.WEBVIEW_TIMEOUT;
+
 import android.content.Context;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -30,6 +32,8 @@
 import android.widget.LinearLayout;
 
 import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class WebViewActivity extends AbstractAutoFillActivity {
 
@@ -70,6 +74,7 @@
     }
 
     public MyWebView loadWebView(UiBot uiBot, boolean usingAppContext) throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
         syncRunOnUiThread(() -> {
             final Context context = usingAppContext ? getApplicationContext() : this;
             mWebView = new MyWebView(context);
@@ -98,13 +103,26 @@
                         throw new IllegalArgumentException("Error opening " + rawPath, e);
                     }
                 }
+
+                @Override
+                public void onPageFinished(WebView view, String url) {
+                    Log.v(TAG, "onPageFinished(): " + url);
+                    latch.countDown();
+                }
+
             });
             mWebView.loadUrl(FAKE_URL);
         });
 
         // Wait until it's loaded.
+
+        if (!latch.await(WEBVIEW_TIMEOUT.ms(), TimeUnit.MILLISECONDS)) {
+            throw new RetryableException(WEBVIEW_TIMEOUT, "WebView not loaded");
+        }
+
+        // TODO(b/80317628): re-add check below
         // NOTE: we cannot search by resourceId because WebView does not set them...
-        uiBot.assertShownByText("Login"); // Login button
+        // uiBot.assertShownByText("Login"); // Login button
 
         return mWebView;
     }
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index 5ca2315..369d566 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -59,7 +59,7 @@
 	$(call all-renderscript-files-under, src)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_PACKAGE_NAME := CtsCameraTestCases
 
diff --git a/tests/camera/AndroidManifest.xml b/tests/camera/AndroidManifest.xml
index cddeaeb..e2ab0be 100644
--- a/tests/camera/AndroidManifest.xml
+++ b/tests/camera/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.camera.cts">
+    package="android.camera.cts"
+    android:targetSandboxVersion="2">
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
diff --git a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
index 92b171a..bd9bec8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
@@ -48,6 +48,7 @@
 import android.hardware.camera2.cts.rs.ScriptYuvToRgb;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.platform.test.annotations.AppModeFull;
 import android.renderscript.Allocation;
 import android.renderscript.Script.LaunchOptions;
 import android.test.AndroidTestCase;
@@ -71,6 +72,7 @@
  *
  * <p>YUV_420_888: flexible YUV420, it is a mandatory format for camera.</p>
  */
+@AppModeFull
 public class AllocationTest extends AndroidTestCase {
     private static final String TAG = "AllocationTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
index 72a5f99..6e0949d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
@@ -30,6 +30,7 @@
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.media.Image;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
 import android.util.Size;
@@ -39,6 +40,7 @@
 /**
  * Basic tests for burst capture in RAW formats.
  */
+@AppModeFull
 public class BurstCaptureRawTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "BurstCaptureRawTest";
     private static final int RAW_FORMATS[] = {
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
index de48dd6..b28106d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
@@ -26,6 +26,7 @@
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.media.Image;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
 import android.util.Size;
@@ -33,6 +34,7 @@
 import java.util.List;
 import java.util.ArrayList;
 
+@AppModeFull
 public class BurstCaptureTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "BurstCaptureTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
index 830e2b6..9a4e42c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -46,6 +46,7 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
 import android.view.Surface;
@@ -76,6 +77,7 @@
 /**
  * <p>Basic test for CameraDevice APIs.</p>
  */
+@AppModeFull
 public class CameraDeviceTest extends Camera2AndroidTestCase {
     private static final String TAG = "CameraDeviceTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 170cc3f..dd7197c8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -32,6 +32,7 @@
 import android.hardware.camera2.cts.helpers.CameraErrorCollector;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -50,6 +51,7 @@
 /**
  * <p>Basic test for CameraManager class.</p>
  */
+@AppModeFull
 public class CameraManagerTest extends AndroidTestCase {
     private static final String TAG = "CameraManagerTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 28a625d..53cce72 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -39,6 +39,7 @@
 import android.hardware.camera2.params.TonemapCurve;
 import android.media.Image;
 import android.os.Parcel;
+import android.platform.test.annotations.AppModeFull;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Range;
@@ -60,6 +61,7 @@
  * manual ISP control and other per-frame control and synchronization.
  * </p>
  */
+@AppModeFull
 public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "CaptureRequestTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
@@ -796,28 +798,6 @@
         }
     }
 
-    /**
-     * Test focal length controls.
-     */
-    public void testFocalLengths() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (mStaticInfo.isHardwareLevelLegacy()) {
-                    Log.i(TAG, "Camera " + id + " is legacy, skipping");
-                    continue;
-                }
-                if (!mStaticInfo.isColorOutputSupported()) {
-                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
-                    continue;
-                }
-                focalLengthTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
     // TODO: add 3A state machine test.
 
     /**
@@ -2499,31 +2479,6 @@
         }
     }
 
-    private void focalLengthTestByCamera() throws Exception {
-        float[] focalLengths = mStaticInfo.getAvailableFocalLengthsChecked();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPreviewSize, listener);
-
-        for(float focalLength : focalLengths) {
-            requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLength);
-            listener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            waitForResultValue(listener, CaptureResult.LENS_STATE,
-                    CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
-
-            verifyCaptureResultForKey(CaptureResult.LENS_FOCAL_LENGTH,
-                    focalLength, listener, NUM_FRAMES_VERIFIED);
-            // This also serves as purpose of showing preview for NUM_FRAMES_VERIFIED
-            verifyCaptureResultForKey(CaptureResult.CONTROL_MODE,
-                    CaptureRequest.CONTROL_MODE_AUTO, listener, NUM_FRAMES_VERIFIED);
-        }
-    }
-
     //----------------------------------------------------------------
     //---------Below are common functions for all tests.--------------
     //----------------------------------------------------------------
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 5923fe2..1be10ee 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -27,6 +27,7 @@
 import android.media.Image;
 import android.media.ImageReader;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Pair;
 import android.util.Size;
 import android.hardware.camera2.cts.helpers.CameraErrorCollector;
@@ -49,6 +50,7 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+@AppModeFull
 public class CaptureResultTest extends Camera2AndroidTestCase {
     private static final String TAG = "CaptureResultTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
@@ -306,6 +308,12 @@
                 multiBuilder.addTarget(previewReader.getSurface());
                 multiBuilder.addTarget(jpegReader.getSurface());
 
+                if (mStaticInfo.isEnableZslSupported()) {
+                    // Turn off ZSL to ensure timestamps are increasing
+                    previewBuilder.set(CaptureRequest.CONTROL_ENABLE_ZSL, false);
+                    multiBuilder.set(CaptureRequest.CONTROL_ENABLE_ZSL, false);
+                }
+
                 CaptureCallback mockCaptureCallback = getMockCaptureListener();
 
                 // Capture targeting only preview
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index 8f32d52..0689b9b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -41,6 +41,7 @@
 import android.media.ImageReader;
 import android.os.ConditionVariable;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
@@ -65,6 +66,7 @@
 /**
  * Tests for the DngCreator API.
  */
+@AppModeFull
 public class DngCreatorTest extends Camera2AndroidTestCase {
     private static final String TAG = "DngCreatorTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 1c53697..22851e6 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -32,6 +32,7 @@
 import android.media.CamcorderProfile;
 import android.media.ImageReader;
 import android.os.Build;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.util.Log;
 import android.util.Rational;
@@ -54,6 +55,7 @@
 /**
  * Extended tests for static camera characteristics.
  */
+@AppModeFull
 public class ExtendedCameraCharacteristicsTest extends AndroidTestCase {
     private static final String TAG = "ExChrsTest"; // must be short so next line doesn't throw
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java b/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java
index 1aa6a17..f0b3179 100644
--- a/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java
@@ -24,6 +24,7 @@
 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
 import android.util.Log;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -35,6 +36,7 @@
 /**
  * <p>Tests for flashlight API.</p>
  */
+@AppModeFull
 public class FlashlightTest extends Camera2AndroidTestCase {
     private static final String TAG = "FlashlightTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/IdleUidTest.java b/tests/camera/src/android/hardware/camera2/cts/IdleUidTest.java
index dd7053b..70e928a 100644
--- a/tests/camera/src/android/hardware/camera2/cts/IdleUidTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/IdleUidTest.java
@@ -32,6 +32,7 @@
 import android.hardware.camera2.CameraManager;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -51,6 +52,7 @@
  * get an error callback losing the camera handle. Similarly if the UID is
  * already idle it cannot obtain a camera handle.
  */
+@AppModeFull
 @RunWith(AndroidJUnit4.class)
 public final class IdleUidTest {
     private static final long CAMERA_OPERATION_TIMEOUT_MILLIS = 5000; // 5 sec
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index 6aa76a8..8852778 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -39,6 +39,7 @@
 import android.media.Image.Plane;
 import android.media.ImageReader;
 import android.os.ConditionVariable;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -66,6 +67,7 @@
  * <p>Some invalid access test. </p>
  * <p>TODO: Add more format tests? </p>
  */
+@AppModeFull
 public class ImageReaderTest extends Camera2AndroidTestCase {
     private static final String TAG = "ImageReaderTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
index 73a391c..65c8eb1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
@@ -28,6 +28,7 @@
 import android.media.Image.Plane;
 import android.media.ImageReader;
 import android.media.ImageWriter;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -44,6 +45,7 @@
  * interface or ImageReader.
  * </p>
  */
+@AppModeFull
 public class ImageWriterTest extends Camera2AndroidTestCase {
     private static final String TAG = "ImageWriterTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index 50d027d..33365b2 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -39,6 +39,7 @@
 import android.media.CamcorderProfile;
 import android.media.Image;
 import android.media.ImageReader;
+import android.platform.test.annotations.AppModeFull;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Range;
@@ -63,6 +64,7 @@
 /**
  * Tests exercising logical camera setup, configuration, and usage.
  */
+@AppModeFull
 public final class LogicalCameraDeviceTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "LogicalCameraTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java b/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java
index 0db73846..9bdb898 100644
--- a/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java
@@ -34,6 +34,7 @@
 import android.media.ImageReader;
 import android.os.SystemClock;
 import android.os.ConditionVariable;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -48,6 +49,7 @@
 /**
  * CameraDevice test by using combination of SurfaceView, TextureView and ImageReader
  */
+@AppModeFull
 public class MultiViewTest extends Camera2MultiViewTestCase {
     private static final String TAG = "MultiViewTest";
     private final static long WAIT_FOR_COMMAND_TO_COMPLETE = 5000; //ms
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
index 06158d8..d54ab17 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
@@ -18,6 +18,7 @@
 
 import android.graphics.SurfaceTexture;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -25,6 +26,7 @@
 /**
  * <p>Basic test for CameraManager class.</p>
  */
+@AppModeFull
 public class NativeCameraDeviceTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "NativeCameraDeviceTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java
index 08e0363..864b7d1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraManagerTest.java
@@ -16,12 +16,14 @@
 
 package android.hardware.camera2.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
 /**
  * <p>Basic test for CameraManager class.</p>
  */
+@AppModeFull
 public class NativeCameraManagerTest extends AndroidTestCase {
     private static final String TAG = "NativeCameraManagerTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
index b018645..fe01fbd 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
@@ -17,11 +17,13 @@
 package android.hardware.camera2.cts;
 
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
 /**
  * <p>Basic test for CameraManager class.</p>
  */
+@AppModeFull
 public class NativeImageReaderTest extends Camera2AndroidTestCase {
     private static final String TAG = "NativeImageReaderTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
index 14b5a22..8882b40 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
@@ -17,6 +17,7 @@
 package android.hardware.camera2.cts;
 
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -24,6 +25,7 @@
 /**
  * <p>Basic test for CameraManager class.</p>
  */
+@AppModeFull
 public class NativeStillCaptureTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "NativeStillCaptureTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 3e79cbc..9006b09 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -39,6 +39,7 @@
 import android.media.ImageWriter;
 import android.os.ConditionVariable;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Range;
@@ -62,6 +63,7 @@
  * Test camera2 API use case performance KPIs, such as camera open time, session creation time,
  * shutter lag etc. The KPI data will be reported in cts results.
  */
+@AppModeFull
 public class PerformanceTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "PerformanceTest";
     private static final String REPORT_LOG_NAME = "CtsCameraTestCases";
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index d2353a1..5bf722c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -39,6 +39,7 @@
 import android.media.MediaRecorder;
 import android.os.Environment;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.util.Range;
@@ -60,6 +61,7 @@
  * CameraDevice video recording use case tests by using MediaRecorder and
  * MediaCodec.
  */
+@AppModeFull
 @LargeTest
 public class RecordingTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "RecordingTest";
diff --git a/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java
index dd49c8d..f30ca92 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java
@@ -32,6 +32,7 @@
 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.hardware.camera2.params.InputConfiguration;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Surface;
@@ -46,6 +47,7 @@
 /**
  * <p>Tests for Reprocess API.</p>
  */
+@AppModeFull
 public class ReprocessCaptureTest extends Camera2SurfaceViewTestCase  {
     private static final String TAG = "ReprocessCaptureTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index 38ed091..cce6171 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -40,6 +40,7 @@
 import android.media.Image;
 import android.media.ImageReader;
 import android.media.ImageWriter;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Size;
 import android.view.Display;
@@ -61,6 +62,7 @@
 /**
  * Tests exercising edge cases in camera setup, configuration, and usage.
  */
+@AppModeFull
 public class RobustnessTest extends Camera2AndroidTestCase {
     private static final String TAG = "RobustnessTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
index 5eddfd1..00ed180 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -29,6 +29,7 @@
 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
 import android.hardware.camera2.params.StreamConfigurationMap;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
@@ -50,6 +51,7 @@
  * Note that most of the tests in this class don't require camera open.
  * </p>
  */
+@AppModeFull
 public class StaticMetadataTest extends Camera2AndroidTestCase {
     private static final String TAG = "StaticMetadataTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
index 9f51fdf..0ef1856 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -29,6 +29,8 @@
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.DngCreator;
+import android.location.Location;
+import android.location.LocationManager;
 import android.media.ImageReader;
 import android.util.Pair;
 import android.util.Size;
@@ -39,6 +41,7 @@
 import android.hardware.camera2.params.MeteringRectangle;
 import android.media.Image;
 import android.os.ConditionVariable;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
 import android.util.Rational;
@@ -52,6 +55,7 @@
 import java.util.Arrays;
 import java.util.List;
 
+@AppModeFull
 public class StillCaptureTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "StillCaptureTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
@@ -503,6 +507,90 @@
     }
 
     /**
+     * Test focal length controls.
+     */
+    public void testFocalLengths() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Camera " + id + " is legacy, skipping");
+                    continue;
+                }
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                focalLengthTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    private void focalLengthTestByCamera() throws Exception {
+        float[] focalLengths = mStaticInfo.getAvailableFocalLengthsChecked();
+        int numStillCaptures = focalLengths.length;
+
+        Size maxStillSz = mOrderedStillSizes.get(0);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder stillRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        Size thumbnailSize = new Size(0, 0);
+        Location sTestLocation = new Location(LocationManager.GPS_PROVIDER);
+        sTestLocation.setTime(1199145600000L);
+        sTestLocation.setLatitude(37.736071);
+        sTestLocation.setLongitude(-122.441983);
+        sTestLocation.setAltitude(21.0);
+        ExifTestData exifTestData = new ExifTestData(
+                /* gpsLocation */ sTestLocation,
+                /* orientation */ 0,
+                /* jpgQuality */ (byte) 80,
+                /* thumbnailQuality */ (byte) 75);
+        setJpegKeys(stillRequest, exifTestData, thumbnailSize, mCollector);
+        CaptureResult result;
+
+        // Set the max number of images to number of focal lengths supported
+        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
+                maxStillSz, resultListener, focalLengths.length, imageListener);
+
+        for(float focalLength : focalLengths) {
+
+            previewRequest.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLength);
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            waitForResultValue(resultListener, CaptureResult.LENS_STATE,
+                    CaptureResult.LENS_STATE_STATIONARY, NUM_RESULTS_WAIT_TIMEOUT);
+            result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            mCollector.expectEquals("Focal length in preview result and request should be the same",
+                    previewRequest.get(CaptureRequest.LENS_FOCAL_LENGTH),
+                    result.get(CaptureResult.LENS_FOCAL_LENGTH));
+
+            stillRequest.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLength);
+            CaptureRequest request = stillRequest.build();
+            resultListener = new SimpleCaptureCallback();
+            mSession.capture(request, resultListener, mHandler);
+            result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            mCollector.expectEquals(
+                    "Focal length in still capture result and request should be the same",
+                    stillRequest.get(CaptureRequest.LENS_FOCAL_LENGTH),
+                    result.get(CaptureResult.LENS_FOCAL_LENGTH));
+
+            Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+
+            validateJpegCapture(image, maxStillSz);
+            verifyJpegKeys(image, result, maxStillSz, thumbnailSize, exifTestData,
+                    mStaticInfo, mCollector);
+        }
+    }
+
+
+    /**
      * Start preview,take a picture and test preview is still running after snapshot
      */
     private void previewPersistenceTestByCamera() throws Exception {
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 89b1926..a1a7e02 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -35,6 +35,7 @@
 import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
 import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
 import android.hardware.camera2.params.OutputConfiguration;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Range;
@@ -53,6 +54,7 @@
 /**
  * CameraDevice preview test by using SurfaceView.
  */
+@AppModeFull
 public class SurfaceViewPreviewTest extends Camera2SurfaceViewTestCase {
     private static final String TAG = "SurfaceViewPreviewTest";
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
index 50c8271..738c3b7 100644
--- a/tests/camera/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -32,6 +32,7 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.platform.test.annotations.AppModeFull;
 
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.MoreAsserts;
@@ -58,6 +59,7 @@
 /**
  * This test case must run with hardware. It can't be tested in emulator
  */
+@AppModeFull
 @LargeTest
 public class CameraGLTest extends ActivityInstrumentationTestCase2<GLSurfaceViewCtsActivity> {
     private static final String TAG = "CameraGLTest";
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 71e9bf0..9efccf1 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -39,6 +39,7 @@
 import android.os.Environment;
 import android.os.Looper;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.MoreAsserts;
 import android.test.UiThreadTest;
@@ -64,6 +65,7 @@
 /**
  * This test case must run with hardware. It can't be tested in emulator
  */
+@AppModeFull
 @LargeTest
 public class CameraTest extends ActivityInstrumentationTestCase2<CameraCtsActivity> {
     private static final String TAG = "CameraTest";
diff --git a/tests/camera/src/android/hardware/cts/Camera_ParametersTest.java b/tests/camera/src/android/hardware/cts/Camera_ParametersTest.java
index b37959e..a614982 100644
--- a/tests/camera/src/android/hardware/cts/Camera_ParametersTest.java
+++ b/tests/camera/src/android/hardware/cts/Camera_ParametersTest.java
@@ -18,7 +18,9 @@
 
 import junit.framework.TestCase;
 import android.hardware.Camera.Parameters;
+import android.platform.test.annotations.AppModeFull;
 
+@AppModeFull
 public class Camera_ParametersTest extends TestCase {
 
     public void testAccessMethods() {
diff --git a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
index 77e75dd..ace3cf7 100644
--- a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
+++ b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
@@ -19,6 +19,7 @@
 import android.hardware.Camera;
 import android.hardware.Camera.Parameters;
 import android.hardware.cts.helpers.CameraUtils;
+import android.platform.test.annotations.AppModeFull;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
@@ -30,6 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 
+@AppModeFull
 @LargeTest
 public class Camera_SizeTest extends CtsAndroidTestCase {
 
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
index 0f48364..6ad8b2e 100644
--- a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
@@ -26,6 +26,7 @@
 import android.hardware.camera2.CameraManager;
 import android.hardware.cts.CameraCtsActivity;
 import android.os.Handler;
+import android.platform.test.annotations.AppModeFull;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
@@ -40,6 +41,7 @@
 /**
  * Tests for multi-process camera usage behavior.
  */
+@AppModeFull
 public class CameraEvictionTest extends ActivityInstrumentationTestCase2<CameraCtsActivity> {
 
     public static final String TAG = "CameraEvictionTest";
diff --git a/tests/framework/base/activitymanager/app_base/Android.mk b/tests/framework/base/activitymanager/app_base/Android.mk
index 4f2bb3c..99a584c 100644
--- a/tests/framework/base/activitymanager/app_base/Android.mk
+++ b/tests/framework/base/activitymanager/app_base/Android.mk
@@ -14,9 +14,6 @@
     $(call all-named-files-under,Components.java, ../app) \
     $(call all-named-files-under,Components.java, ../app27) \
 
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
 LOCAL_MODULE := cts-am-app-base
 
 LOCAL_SDK_VERSION := current
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index 36be03a..1d2bd3e 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -78,7 +78,9 @@
     @Presubmit
     @Test
     public void testTranslucentActivityOnTopOfPinnedStack() throws Exception {
-        assumeTrue(supportsPip());
+        if (!supportsPip()) {
+            return;
+        }
 
         executeShellCommand(getAmStartCmdOverHome(LAUNCH_PIP_ON_PIP_ACTIVITY));
         mAmWmState.waitForValidState(LAUNCH_PIP_ON_PIP_ACTIVITY);
@@ -107,7 +109,9 @@
      */
     @Test
     public void testTranslucentActivityOnTopOfHome() throws Exception {
-        assumeTrue(hasHomeScreen());
+        if (!hasHomeScreen()) {
+            return;
+        }
 
         launchHomeActivity();
         launchActivity(ALWAYS_FOCUSABLE_PIP_ACTIVITY);
@@ -125,7 +129,9 @@
     @Presubmit
     @Test
     public void testHomeVisibleOnActivityTaskPinned() throws Exception {
-        assumeTrue(supportsPip());
+        if (!supportsPip()) {
+            return;
+        }
 
         launchHomeActivity();
         launchActivity(TEST_ACTIVITY);
@@ -150,7 +156,10 @@
     @Presubmit
     @Test
     public void testTranslucentActivityOverDockedStack() throws Exception {
-        assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no multi-window support
+            return;
+        }
 
         launchActivitiesInSplitScreen(
                 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
@@ -184,7 +193,10 @@
     @Presubmit
     @Test
     public void testFinishActivityInNonFocusedStack() throws Exception {
-        assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no multi-window support
+            return;
+        }
 
         // Launch two activities in docked stack.
         launchActivityInSplitScreenWithRecents(LAUNCHING_ACTIVITY);
@@ -231,7 +243,9 @@
         // Launch a different activity on top.
         launchActivity(BROADCAST_RECEIVER_ACTIVITY);
         mAmWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
-        mAmWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, false);
+        final boolean shouldBeVisible =
+                !mAmWmState.getAmState().isBehindOpaqueActivities(MOVE_TASK_TO_BACK_ACTIVITY);
+        mAmWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, shouldBeVisible);
         mAmWmState.assertVisibility(BROADCAST_RECEIVER_ACTIVITY, true);
 
         // Finish the top-most activity.
@@ -335,7 +349,9 @@
      */
     @Test
     public void testNoHistoryActivityFinishedResumedActivityNotIdle() throws Exception {
-        assumeTrue(hasHomeScreen());
+        if (!hasHomeScreen()) {
+            return;
+        }
 
         // Start with home on top
         launchHomeActivity();
@@ -366,7 +382,9 @@
 
     @Test
     public void testTurnScreenOnAttrWithLockScreen() throws Exception {
-        assumeTrue(supportsSecureLock());
+        if (!supportsSecureLock()) {
+            return;
+        }
 
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.setLockCredential()
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index dc15923..0ce9dcf 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -20,6 +20,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.server.am.ActivityAndWindowManagersState.dpToPx;
 import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ComponentNameUtils.getWindowName;
@@ -48,7 +50,10 @@
 import static org.hamcrest.Matchers.lessThan;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
 import android.content.ComponentName;
@@ -77,6 +82,8 @@
     // Shell command to request portrait orientation to {@link #BROADCAST_RECEIVER_ACTIVITY}.
     private static final String REQUEST_PORTRAIT_BROADCAST = "am broadcast -a "
             + ACTION_TRIGGER_BROADCAST + " --ei " + EXTRA_BROADCAST_ORIENTATION + " 1";
+    private static final String REQUEST_LANDSCAPE_BROADCAST = "am broadcast -a "
+            + ACTION_TRIGGER_BROADCAST + " --ei " + EXTRA_BROADCAST_ORIENTATION + " 0";
 
     private static final int SMALL_WIDTH_DP = 426;
     private static final int SMALL_HEIGHT_DP = 320;
@@ -392,6 +399,90 @@
         //         1 /* portrait */, updatedReportedSizes.orientation);
     }
 
+    /**
+     * Test that device handles consequent requested orientations and will not report a config
+     * change to an invisible activity.
+     */
+    @Test
+    public void testAppOrientationRequestConfigChanges() {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
+
+        LogSeparator logSeparator = separateLogs();
+        launchActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+        mAmWmState.assertVisibility(PORTRAIT_ORIENTATION_ACTIVITY, true /* visible */);
+
+        assertLifecycleCounts(PORTRAIT_ORIENTATION_ACTIVITY, logSeparator, 1 /* create */,
+                1 /* start */, 1 /* resume */, 0 /* pause */, 0 /* stop */, 0 /* destroy */,
+                0 /* config */);
+
+        launchActivity(LANDSCAPE_ORIENTATION_ACTIVITY);
+        mAmWmState.assertVisibility(LANDSCAPE_ORIENTATION_ACTIVITY, true /* visible */);
+
+        assertLifecycleCounts(PORTRAIT_ORIENTATION_ACTIVITY, logSeparator, 1 /* create */,
+                1 /* start */, 1 /* resume */, 1 /* pause */, 1 /* stop */, 0 /* destroy */,
+                0 /* config */);
+        assertLifecycleCounts(LANDSCAPE_ORIENTATION_ACTIVITY, logSeparator, 1 /* create */,
+                1 /* start */, 1 /* resume */, 0 /* pause */, 0 /* stop */, 0 /* destroy */,
+                0 /* config */);
+
+        launchActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+        mAmWmState.assertVisibility(PORTRAIT_ORIENTATION_ACTIVITY, true /* visible */);
+
+        assertLifecycleCounts(PORTRAIT_ORIENTATION_ACTIVITY, logSeparator, 2 /* create */,
+                2 /* start */, 2 /* resume */, 1 /* pause */, 1 /* stop */, 0 /* destroy */,
+                0 /* config */);
+        assertLifecycleCounts(LANDSCAPE_ORIENTATION_ACTIVITY, logSeparator, 1 /* create */,
+                1 /* start */, 1 /* resume */, 1 /* pause */, 1 /* stop */, 0 /* destroy */,
+                0 /* config */);
+    }
+
+    /**
+     * Test that device orientation is restored when an activity that requests it is no longer
+     * visible.
+     */
+    @Test
+    public void testAppOrientationRequestConfigClears() {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
+
+        LogSeparator logSeparator = separateLogs();
+        launchActivity(TEST_ACTIVITY);
+        mAmWmState.assertVisibility(TEST_ACTIVITY, true /* visible */);
+        final ReportedSizes initialReportedSizes =
+                getLastReportedSizesForActivity(TEST_ACTIVITY, logSeparator);
+        final int  initialOrientation = initialReportedSizes.orientation;
+
+
+        // Launch an activity that requests different orientation and check that it will be applied
+        final boolean launchingPortrait;
+        if (initialOrientation == 2 /* landscape */) {
+            launchingPortrait = true;
+        } else if (initialOrientation == 1 /* portrait */) {
+            launchingPortrait = false;
+        } else {
+            fail("Unexpected orientation value: " + initialOrientation);
+            return;
+        }
+        final ComponentName differentOrientationActivity = launchingPortrait
+                ? PORTRAIT_ORIENTATION_ACTIVITY : LANDSCAPE_ORIENTATION_ACTIVITY;
+        logSeparator = separateLogs();
+        launchActivity(differentOrientationActivity);
+        mAmWmState.assertVisibility(differentOrientationActivity, true /* visible */);
+        final ReportedSizes rotatedReportedSizes =
+                getLastReportedSizesForActivity(differentOrientationActivity, logSeparator);
+        assertEquals("Applied orientation must correspond to activity request",
+                launchingPortrait ? 1 : 2, rotatedReportedSizes.orientation);
+
+        // Launch another activity on top and check that its orientation is not affected by previous
+        // activity.
+        logSeparator = separateLogs();
+        launchActivity(RESIZEABLE_ACTIVITY);
+        mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY, true /* visible */);
+        final ReportedSizes finalReportedSizes =
+                getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY, logSeparator);
+        assertEquals("Applied orientation must not be influenced by previously visible activity",
+                initialOrientation, finalReportedSizes.orientation);
+    }
+
     // TODO(b/70870253): This test seems malfunction.
     @Ignore("b/70870253")
     @Test
@@ -424,7 +515,7 @@
      * Test that device handles moving between two tasks with different orientations.
      */
     @Test
-    public void testTaskCloseRestoreOrientation() {
+    public void testTaskCloseRestoreFixedOrientation() {
         assumeTrue("Skipping test: no rotation support", supportsRotation());
 
         // Start landscape activity.
@@ -438,7 +529,7 @@
 
         // Request portrait
         executeShellCommand(REQUEST_PORTRAIT_BROADCAST);
-        mAmWmState.waitForRotation(1);
+        mAmWmState.waitForLastOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
         // Finish activity
         executeShellCommand(FINISH_ACTIVITY_BROADCAST);
@@ -452,6 +543,146 @@
     /**
      * Test that device handles moving between two tasks with different orientations.
      */
+    @Test
+    public void testTaskCloseRestoreFreeOrientation() {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
+
+        // Start landscape activity.
+        launchActivity(RESIZEABLE_ACTIVITY);
+        mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY, true /* visible */);
+        final int initialServerOrientation = mAmWmState.getWmState().getLastOrientation();
+
+        // Verify fixed-landscape
+        LogSeparator logSeparator = separateLogs();
+        launchActivityInNewTask(BROADCAST_RECEIVER_ACTIVITY);
+        executeShellCommand(REQUEST_LANDSCAPE_BROADCAST);
+        mAmWmState.waitForLastOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        executeShellCommand(FINISH_ACTIVITY_BROADCAST);
+
+        // Verify that activity brought to front is in originally requested orientation.
+        mAmWmState.waitForActivityState(RESIZEABLE_ACTIVITY, STATE_RESUMED);
+        ReportedSizes reportedSizes = getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY,
+                logSeparator);
+        assertNull("Should come back in original orientation", reportedSizes);
+        assertEquals("Should come back in original server orientation",
+                initialServerOrientation, mAmWmState.getWmState().getLastOrientation());
+        assertRelaunchOrConfigChanged(RESIZEABLE_ACTIVITY, 0 /* numRelaunch */,
+                0 /* numConfigChange */, logSeparator);
+
+        // Verify fixed-portrait
+        logSeparator = separateLogs();
+        launchActivityInNewTask(BROADCAST_RECEIVER_ACTIVITY);
+        executeShellCommand(REQUEST_PORTRAIT_BROADCAST);
+        mAmWmState.waitForLastOrientation(SCREEN_ORIENTATION_PORTRAIT);
+        executeShellCommand(FINISH_ACTIVITY_BROADCAST);
+
+        // Verify that activity brought to front is in originally requested orientation.
+        mAmWmState.waitForActivityState(RESIZEABLE_ACTIVITY, STATE_RESUMED);
+        reportedSizes = getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY, logSeparator);
+        assertNull("Should come back in original orientation", reportedSizes);
+        assertEquals("Should come back in original server orientation",
+                initialServerOrientation, mAmWmState.getWmState().getLastOrientation());
+        assertRelaunchOrConfigChanged(RESIZEABLE_ACTIVITY, 0 /* numRelaunch */,
+                0 /* numConfigChange */, logSeparator);
+    }
+
+    /**
+     * Test that activity orientation will change when device is rotated.
+     * Also verify that occluded activity will not get config changes.
+     */
+    @Test
+    public void testAppOrientationWhenRotating() throws Exception {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
+
+        // Start resizeable activity that handles configuration changes.
+        LogSeparator logSeparator = separateLogs();
+        launchActivity(TEST_ACTIVITY);
+        launchActivity(RESIZEABLE_ACTIVITY);
+        mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY, true /* visible */);
+
+        final int displayId = mAmWmState.getAmState().getDisplayByActivity(RESIZEABLE_ACTIVITY);
+
+        // Rotate the activity and check that it receives configuration changes with a different
+        // orientation each time.
+        try (final RotationSession rotationSession = new RotationSession()) {
+            rotationSession.set(ROTATION_0);
+            ReportedSizes reportedSizes =
+                    getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY, logSeparator);
+            int prevOrientation = reportedSizes.orientation;
+
+            final int[] rotations = { ROTATION_270, ROTATION_180, ROTATION_90, ROTATION_0 };
+            for (final int rotation : rotations) {
+                logSeparator = separateLogs();
+                rotationSession.set(rotation);
+                final int newDeviceRotation = getDeviceRotation(displayId);
+                if (rotation != newDeviceRotation) {
+                    log("This device doesn't support locked user "
+                            + "rotation mode. Not continuing the rotation checks.");
+                    continue;
+                }
+
+                // Verify lifecycle count and orientation changes.
+                assertRelaunchOrConfigChanged(RESIZEABLE_ACTIVITY, 0 /* numRelaunch */,
+                        1 /* numConfigChange */, logSeparator);
+                reportedSizes =
+                        getLastReportedSizesForActivity(RESIZEABLE_ACTIVITY, logSeparator);
+                assertNotEquals(prevOrientation, reportedSizes.orientation);
+                assertRelaunchOrConfigChanged(TEST_ACTIVITY, 0 /* numRelaunch */,
+                        0 /* numConfigChange */, logSeparator);
+
+                prevOrientation = reportedSizes.orientation;
+            }
+        }
+    }
+
+    /**
+     * Test that activity orientation will not change when trying to rotate fixed-orientation
+     * activity.
+     * Also verify that occluded activity will not get config changes.
+     */
+    @Test
+    public void testFixedOrientationWhenRotating() throws Exception {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
+
+        // Start portrait-fixed activity
+        LogSeparator logSeparator = separateLogs();
+        launchActivity(RESIZEABLE_ACTIVITY);
+        launchActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+        mAmWmState.assertVisibility(PORTRAIT_ORIENTATION_ACTIVITY, true /* visible */);
+
+        final int displayId = mAmWmState.getAmState()
+                .getDisplayByActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+
+        // Rotate the activity and check that the orientation doesn't change
+        try (final RotationSession rotationSession = new RotationSession()) {
+            rotationSession.set(ROTATION_0);
+
+            final int[] rotations = { ROTATION_270, ROTATION_180, ROTATION_90, ROTATION_0 };
+            for (final int rotation : rotations) {
+                logSeparator = separateLogs();
+                rotationSession.set(rotation);
+                final int newDeviceRotation = getDeviceRotation(displayId);
+                if (rotation != newDeviceRotation) {
+                    log("This device doesn't support locked user "
+                            + "rotation mode. Not continuing the rotation checks.");
+                    continue;
+                }
+
+                // Verify lifecycle count and orientation changes.
+                assertRelaunchOrConfigChanged(PORTRAIT_ORIENTATION_ACTIVITY, 0 /* numRelaunch */,
+                        0 /* numConfigChange */, logSeparator);
+                final ReportedSizes reportedSizes = getLastReportedSizesForActivity(
+                        PORTRAIT_ORIENTATION_ACTIVITY, logSeparator);
+                assertNull("No new sizes must be reported", reportedSizes);
+                assertRelaunchOrConfigChanged(RESIZEABLE_ACTIVITY, 0 /* numRelaunch */,
+                        0 /* numConfigChange */, logSeparator);
+            }
+        }
+    }
+
+    /**
+     * Test that device handles moving between two tasks with different orientations.
+     */
     @Presubmit
     @Test
     @FlakyTest(bugId = 71792393)
@@ -469,7 +700,7 @@
 
         // Request portrait
         executeShellCommand(REQUEST_PORTRAIT_BROADCAST);
-        mAmWmState.waitForRotation(1);
+        mAmWmState.waitForLastOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
         // Finish activity
         executeShellCommand(MOVE_TASK_TO_BACK_BROADCAST);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
index 2acf3ac..7873dbe 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
@@ -274,7 +274,10 @@
                     EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY));
             waitForValidStateWithActivityTypeAndWindowingMode(
                     TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD, WINDOWING_MODE_FULLSCREEN);
-            mAmWmState.assertHomeActivityVisible(false);
+            boolean isTranslucent = mAmWmState.getAmState().isActivityTranslucent(TEST_ACTIVITY);
+            // Home should be visible if the occluding activity is translucent, else home shouldn't
+            // be visible.
+            mAmWmState.assertHomeActivityVisible(isTranslucent);
             pressBackButton();
             mAmWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
             assertAssistantStackExists();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerTransitionSelectionTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerTransitionSelectionTests.java
index 32dbce9..4828c34 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerTransitionSelectionTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerTransitionSelectionTests.java
@@ -40,6 +40,8 @@
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.FlakyTest;
 
+import org.junit.Assume;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -58,6 +60,17 @@
 @FlakyTest(bugId = 71792333)
 public class ActivityManagerTransitionSelectionTests extends ActivityManagerTestBase {
 
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Transition selection tests are currently disabled on Wear because
+        // config_windowSwipeToDismiss is set to true, which breaks all kinds of assumptions in the
+        // transition selection logic.
+        Assume.assumeTrue(!isWatch());
+    }
+
     // Test activity open/close under normal timing
     @Test
     public void testOpenActivity_NeitherWallpaper() {
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index 003f89b..5d2d82b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -35,6 +35,7 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.content.ComponentName;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -102,8 +103,10 @@
             lockScreenSession.enterAndConfirmLockCredential();
             mAmWmState.waitForKeyguardGone();
             mAmWmState.assertKeyguardGone();
+            boolean isDismissTranslucent =
+                    mAmWmState.getAmState().isActivityTranslucent(DISMISS_KEYGUARD_ACTIVITY);
             mAmWmState.assertVisibility(DISMISS_KEYGUARD_ACTIVITY, true);
-            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, false);
+            mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, isDismissTranslucent);
         }
     }
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index c912e6e..f76979c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -5,12 +5,15 @@
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback
         .ON_MULTI_WINDOW_MODE_CHANGED;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_NEW_INTENT;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
 
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
@@ -126,6 +129,35 @@
         return new Pair<>(activity, stage);
     }
 
+    /**
+     * Returns a pair of the activity and the state it should be in based on the configuration of
+     * occludingActivity.
+     */
+    static Pair<Activity, ActivityCallback> occludedActivityState(
+            Activity activity, Activity occludingActivity) {
+        return occludedActivityState(activity, isTranslucent(occludingActivity));
+    }
+
+    /**
+     * Returns a pair of the activity and the state it should be in based on
+     * occludingActivityIsTranslucent.
+     */
+    static Pair<Activity, ActivityCallback> occludedActivityState(
+            Activity activity, boolean occludingActivityIsTranslucent) {
+        // Activities behind a translucent activity should be in the paused state since they are
+        // still visible. Otherwise, they should be in the stopped state.
+        return new Pair<>(activity, occludedActivityState(occludingActivityIsTranslucent));
+    }
+
+    static ActivityCallback occludedActivityState(boolean occludingActivityIsTranslucent) {
+        return occludingActivityIsTranslucent ? ON_PAUSE : ON_STOP;
+    }
+
+    /** Returns true if the input activity is translucent. */
+    static boolean isTranslucent(Activity activity) {
+        return ActivityInfo.isTranslucentOrFloating(activity.getWindow().getWindowStyle());
+    }
+
     // Test activity
     public static class FirstActivity extends Activity {
     }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index 7c04612..881d002 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -2,6 +2,7 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.server.am.ActivityManagerState.STATE_PAUSED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
 import static android.server.am.UiDeviceUtils.pressBackButton;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
@@ -22,12 +23,14 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
+import android.app.Instrumentation.ActivityMonitor;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
@@ -68,11 +71,11 @@
 
         getLifecycleLog().clear();
         final Activity secondActivity = mSecondActivityTestRule.launchActivity(new Intent());
-        waitAndAssertActivityStates(state(firstActivity, ON_STOP),
+        waitAndAssertActivityStates(occludedActivityState(firstActivity, secondActivity),
                 state(secondActivity, ON_RESUME));
 
         LifecycleVerifier.assertLaunchSequence(SecondActivity.class, FirstActivity.class,
-                getLifecycleLog());
+                getLifecycleLog(), isTranslucent(secondActivity));
     }
 
     @Test
@@ -118,25 +121,34 @@
         final Activity stoppedActivity = mFirstActivityTestRule.launchActivity(new Intent());
         final Activity topActivity = mSecondActivityTestRule.launchActivity(new Intent());
 
-        waitAndAssertActivityStates(state(stoppedActivity, ON_STOP), state(topActivity, ON_RESUME));
+        waitAndAssertActivityStates(
+                occludedActivityState(stoppedActivity, topActivity), state(topActivity, ON_RESUME));
 
         getLifecycleLog().clear();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(stoppedActivity::recreate);
-        waitAndAssertActivityStates(state(stoppedActivity, ON_STOP));
+        waitAndAssertActivityStates(occludedActivityState(stoppedActivity, topActivity));
 
-        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_STOP);
+        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(),
+                occludedActivityState(isTranslucent(topActivity)));
     }
 
     @Test
     public void testRelaunchConfigurationChangedWhileBecomingVisible() throws Exception {
+        if (!supportsRotation()) {
+            // Skip rotation test if device doesn't support it.
+            return;
+        }
+
         final Activity becomingVisibleActivity =
                 mFirstActivityTestRule.launchActivity(new Intent());
         final Activity translucentActivity =
                 mTranslucentActivityTestRule.launchActivity(new Intent());
         final Activity topOpaqueActivity = mSecondActivityTestRule.launchActivity(new Intent());
 
-        waitAndAssertActivityStates(state(becomingVisibleActivity, ON_STOP),
-                state(translucentActivity, ON_STOP), state(topOpaqueActivity, ON_RESUME));
+        waitAndAssertActivityStates(
+                occludedActivityState(becomingVisibleActivity, topOpaqueActivity),
+                occludedActivityState(translucentActivity, topOpaqueActivity),
+                state(topOpaqueActivity, ON_RESUME));
 
         getLifecycleLog().clear();
         try (final RotationSession rotationSession = new RotationSession()) {
@@ -193,8 +205,7 @@
                 mFirstActivityTestRule.launchActivity(new Intent());
 
         // Launch translucent activity on top
-        final Activity translucentActivity =
-                mTranslucentActivityTestRule.launchActivity(new Intent());
+        mTranslucentActivityTestRule.launchActivity(new Intent());
 
         // Launch another translucent activity on top to make sure the fullscreen activity
         // transitions to final state
@@ -225,25 +236,38 @@
 
         // Wait for top activity to resume
         waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
-                state(translucentActivity, ON_STOP), state(firstActivity, ON_STOP));
+                occludedActivityState(translucentActivity, secondActivity),
+                occludedActivityState(firstActivity, secondActivity));
 
         getLifecycleLog().clear();
 
+        final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
+                secondActivity.getWindow().getWindowStyle());
+
         // Finish top activity
         mSecondActivityTestRule.finishActivity();
 
-        // Wait for translucent activity to resume
-        waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
-                state(firstActivity, ON_PAUSE));
+        if (secondActivityIsTranslucent) {
+            // In this case we don't expect the state of the firstActivity to change since it is
+            // already in the visible paused state. So, we just verify that translucentActivity
+            // transitions to resumed state.
+            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+        } else {
+            // Wait for translucent activity to resume
+            waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+                    state(firstActivity, ON_START));
 
-        // Verify that the first activity was restarted to pause
-        LifecycleVerifier.assertRestartAndPauseSequence(FirstActivity.class, getLifecycleLog());
+            // Verify that the first activity was restarted
+            LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
+        }
     }
 
     @Test
     public void testPausedWhenRecreatedFromInNonFocusedStack() throws Exception {
-        assumeTrue("Skipping test: no split multi-window support",
-                supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no split multi-window support
+            return;
+        }
 
         // Launch first activity
         final Activity firstActivity =
@@ -278,9 +302,71 @@
     }
 
     @Test
+    public void testResultInNonFocusedStack() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no split multi-window support
+            return;
+        }
+
+        // Launch first activity
+        final Activity callbackTrackingActivity =
+                mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+        // Wait for first activity to resume
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+
+        // Enter split screen
+        moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId(),
+                true /* launchSideActivityIfNeeded */);
+
+        // Launch second activity to pause first
+        // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
+        ActivityMonitor activityMonitor = InstrumentationRegistry.getInstrumentation()
+                .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
+                        false /* block */);
+
+        callbackTrackingActivity.startActivityForResult(
+                new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
+
+        // Wait for the ActivityMonitor to be hit
+        final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
+                .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
+
+        // Wait for second activity to resume
+        assertNotNull("Second activity should be started", secondActivity);
+        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+
+        // Start an activity in separate task (will be placed in secondary stack)
+        getLaunchActivityBuilder().execute();
+
+        waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
+
+        // Finish top activity and verify that activity below became focused.
+        getLifecycleLog().clear();
+        secondActivity.setResult(Activity.RESULT_OK);
+        secondActivity.finish();
+
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_START));
+        LifecycleVerifier.assertRestartSequence(CallbackTrackingActivity.class, getLifecycleLog());
+
+        // Bring the first activity to front to verify that it receives the result.
+        getLifecycleLog().clear();
+        final Intent singleTopIntent = new Intent(InstrumentationRegistry.getTargetContext(),
+                CallbackTrackingActivity.class);
+        singleTopIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+        InstrumentationRegistry.getTargetContext().startActivity(singleTopIntent);
+
+        waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+                Arrays.asList(ON_ACTIVITY_RESULT, ON_NEW_INTENT, ON_RESUME), "bring to front");
+    }
+
+    @Test
     public void testPausedWhenRestartedFromInNonFocusedStack() throws Exception {
-        assumeTrue("Skipping test: no split multi-window support",
-                supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no split multi-window support
+            return;
+        }
 
         // Launch first activity
         final Activity firstActivity =
@@ -342,10 +428,17 @@
         final Intent intent = new Intent();
         intent.putExtra(EXTRA_FINISH_AFTER_RESUME, true);
         mLaunchForResultActivityTestRule.launchActivity(intent);
+        final boolean isTranslucent = isTranslucent(mLaunchForResultActivityTestRule.getActivity());
 
-        final List<LifecycleLog.ActivityCallback> expectedSequence =
-                Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
-                        ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> expectedSequence;
+        if (isTranslucent) {
+            expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+                    ON_RESUME, ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME);
+        } else {
+            expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+                    ON_RESUME, ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START,
+                    ON_RESUME);
+        }
         waitForActivityTransitions(LaunchForResultActivity.class, expectedSequence);
 
         LifecycleVerifier.assertSequence(LaunchForResultActivity.class,
@@ -430,18 +523,24 @@
         waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
 
         // Wait for first activity to become stopped
-        waitAndAssertActivityStates(state(trackingActivity, ON_STOP));
+        waitAndAssertActivityStates(occludedActivityState(trackingActivity, secondActivity));
 
         // Call "recreate" and assert sequence
         getLifecycleLog().clear();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(trackingActivity::recreate);
-        waitAndAssertActivityStates(state(trackingActivity, ON_STOP));
+        waitAndAssertActivityStates(occludedActivityState(trackingActivity, secondActivity));
 
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class,
-                getLifecycleLog(),
-                Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
-                        ON_RESUME, ON_PAUSE, ON_STOP),
-                "recreate");
+        final List<LifecycleLog.ActivityCallback> callbacks;
+        if (isTranslucent(secondActivity)) {
+            callbacks = Arrays.asList(ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                    ON_POST_CREATE, ON_RESUME, ON_PAUSE);
+        } else {
+            callbacks = Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                    ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_STOP);
+        }
+
+        LifecycleVerifier.assertSequence(
+                CallbackTrackingActivity.class, getLifecycleLog(), callbacks, "recreate");
     }
 
     /**
@@ -458,10 +557,17 @@
 
         // Start activity in another process to put original activity in background.
         mFirstActivityTestRule.launchActivity(new Intent());
-        mAmWmState.waitForActivityState(targetActivity, STATE_STOPPED);
+        final boolean isTranslucent = isTranslucent(mFirstActivityTestRule.getActivity());
+        mAmWmState.waitForActivityState(
+                targetActivity, isTranslucent ? STATE_PAUSED : STATE_STOPPED);
 
-        // Kill first activity
-        AmUtils.runKill(targetActivity.getPackageName(), true /* wait */);
+        // Only try to kill targetActivity if the top activity isn't translucent. If the top
+        // activity is translucent then targetActivity will be visible, so the process will be
+        // started again really quickly.
+        if (!isTranslucent) {
+            // Kill first activity
+            AmUtils.runKill(targetActivity.getPackageName(), true /* wait */);
+        }
 
         // Return back to first activity
         pressBackButton();
@@ -481,10 +587,12 @@
         Activity recreatingActivity = mSingleTopActivityTestRule.launchActivity(new Intent());
 
         // Launch second activity to cover and stop first
-        getLaunchActivityBuilder().setNewTask(true).setMultipleTask(true).execute();
+        final LaunchActivityBuilder launchActivityBuilder = getLaunchActivityBuilder();
+        launchActivityBuilder.setNewTask(true).setMultipleTask(true).execute();
 
         // Wait for first activity to become stopped
-        waitAndAssertActivityStates(state(recreatingActivity, ON_STOP));
+        waitAndAssertActivityStates(occludedActivityState(recreatingActivity,
+                launchActivityBuilder.isTargetActivityTranslucent()));
 
         // Launch the activity again to recreate
         getLifecycleLog().clear();
@@ -495,9 +603,17 @@
         InstrumentationRegistry.getTargetContext().startActivity(intent);
 
         // Wait for activity to relaunch and resume
-        final List<LifecycleLog.ActivityCallback> expectedRelaunchSequence =
-                Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
-                        ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> expectedRelaunchSequence;
+        if (launchActivityBuilder.isTargetActivityTranslucent()) {
+            expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_STOP,
+                    ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+                    ON_PAUSE, ON_RESUME);
+        } else {
+            expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME,
+                    ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+                    ON_POST_CREATE, ON_RESUME);
+        }
+
         waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequence);
         LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
                 expectedRelaunchSequence, "recreate");
@@ -547,7 +663,7 @@
 
         // Wait for the activity to resume
         waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-        waitAndAssertActivityStates(state(singleTopActivity, ON_STOP));
+        waitAndAssertActivityStates(occludedActivityState(singleTopActivity, secondActivity));
 
         // Try to launch again
         getLifecycleLog().clear();
@@ -560,10 +676,15 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_RESUME));
 
         // Verify that the first activity was restarted, new intent was delivered and resumed again
-        final List<LifecycleLog.ActivityCallback> expectedSequence =
-                Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME);
-        final List<LifecycleLog.ActivityCallback> otherSequence =
-                Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME);
+        final List<LifecycleLog.ActivityCallback> expectedSequence;
+        final List<LifecycleLog.ActivityCallback> otherSequence;
+        if (isTranslucent(singleTopActivity)) {
+            expectedSequence = Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_RESUME);
+            otherSequence = Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME);
+        } else {
+            expectedSequence = Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME);
+            otherSequence = Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME);
+        }
         // TODO(b/65236456): This should always be ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME
         LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
                 Arrays.asList(expectedSequence, otherSequence), "newIntent");
@@ -609,8 +730,10 @@
 
     @Test
     public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
-        assumeTrue("Skipping test: no split multi-window support",
-                supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no split multi-window support
+            return;
+        }
 
         // Launch a singleTop activity
         final Activity testActivity =
@@ -654,8 +777,10 @@
 
     @Test
     public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
-        assumeTrue("Skipping test: no split multi-window support",
-                supportsSplitScreenMultiWindow());
+        if (!supportsSplitScreenMultiWindow()) {
+            // Skipping test: no split multi-window support
+            return;
+        }
 
         // Launch a singleTop activity
         final Activity testActivity =
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
index 8539ec8..8c87439 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
@@ -38,18 +38,30 @@
     }
 
     static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
-            Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog) {
+            Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog,
+            boolean launchingIsTranslucent) {
         final List<Pair<String, ActivityCallback>> observedTransitions = lifecycleLog.getLog();
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(launchingActivity, "launch");
 
-        final List<Pair<String, ActivityCallback>> expectedTransitions = Arrays.asList(
-                transition(existingActivity, ON_PAUSE),
-                transition(launchingActivity, PRE_ON_CREATE),
-                transition(launchingActivity, ON_CREATE),
-                transition(launchingActivity, ON_START),
-                transition(launchingActivity, ON_RESUME),
-                transition(existingActivity, ON_STOP));
+        final List<Pair<String, ActivityCallback>> expectedTransitions;
+        if (launchingIsTranslucent) {
+            expectedTransitions = Arrays.asList(
+                    transition(existingActivity, ON_PAUSE),
+                    transition(launchingActivity, PRE_ON_CREATE),
+                    transition(launchingActivity, ON_CREATE),
+                    transition(launchingActivity, ON_START),
+                    transition(launchingActivity, ON_RESUME));
+        } else {
+            expectedTransitions = Arrays.asList(
+                    transition(existingActivity, ON_PAUSE),
+                    transition(launchingActivity, PRE_ON_CREATE),
+                    transition(launchingActivity, ON_CREATE),
+                    transition(launchingActivity, ON_START),
+                    transition(launchingActivity, ON_RESUME),
+                    transition(existingActivity, ON_STOP));
+        }
+
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
@@ -77,6 +89,18 @@
         assertEquals(errorMessage, expectedTransitions, observedTransitions);
     }
 
+    static void assertRestartSequence(Class<? extends Activity> activityClass,
+            LifecycleLog lifecycleLog) {
+        final List<ActivityCallback> observedTransitions =
+                lifecycleLog.getActivityLog(activityClass);
+        log("Observed sequence: " + observedTransitions);
+        final String errorMessage = errorDuringTransition(activityClass, "restart");
+
+        final List<ActivityCallback> expectedTransitions =
+                Arrays.asList(ON_RESTART, ON_START);
+        assertEquals(errorMessage, expectedTransitions, observedTransitions);
+    }
+
     static void assertRestartAndPauseSequence(Class<? extends Activity> activityClass,
                                               LifecycleLog lifecycleLog) {
         final List<ActivityCallback> observedTransitions =
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
index 11e1929..fe1f588 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
@@ -254,11 +254,21 @@
                 "***Waiting for Keyguard gone...");
     }
 
+    /** Wait for specific rotation for the default display. Values are Surface#Rotation */
     void waitForRotation(int rotation) {
         waitForWithWmState(state -> state.getRotation() == rotation,
                 "***Waiting for Rotation: " + rotation);
     }
 
+    /**
+     * Wait for specific orientation for the default display.
+     * Values are ActivityInfo.ScreenOrientation
+     */
+    void waitForLastOrientation(int orientation) {
+        waitForWithWmState(state -> state.getLastOrientation() == orientation,
+                "***Waiting for LastOrientation: " + orientation);
+    }
+
     void waitForDisplayUnfrozen() {
         waitForWithWmState(state -> !state.isDisplayFrozen(),
                 "***Waiting for Display unfrozen");
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
index 2338339..d50e622 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
@@ -327,6 +327,15 @@
         return -1;
     }
 
+    /** Get display id by activity on it. */
+    int getDisplayByActivity(ComponentName activityComponent) {
+        final ActivityManagerState.ActivityTask task = getTaskByActivity(activityComponent);
+        if (task == null) {
+            return -1;
+        }
+        return getStackById(task.mStackId).mDisplayId;
+    }
+
     List<ActivityDisplay> getDisplays() {
         return new ArrayList<>(mDisplays);
     }
@@ -382,6 +391,38 @@
         return false;
     }
 
+    boolean isActivityTranslucent(ComponentName activityName) {
+        final String fullName = getActivityName(activityName);
+        for (ActivityStack stack : mStacks) {
+            for (ActivityTask task : stack.mTasks) {
+                for (Activity activity : task.mActivities) {
+                    if (activity.name.equals(fullName)) {
+                        return activity.translucent;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    boolean isBehindOpaqueActivities(ComponentName activityName) {
+        final String fullName = getActivityName(activityName);
+        for (ActivityStack stack : mStacks) {
+            for (ActivityTask task : stack.mTasks) {
+                for (Activity activity : task.mActivities) {
+                    if (activity.name.equals(fullName)) {
+                        return false;
+                    }
+                    if (!activity.translucent) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
     boolean containsStartedActivities() {
         for (ActivityStack stack : mStacks) {
             for (ActivityTask task : stack.mTasks) {
@@ -623,13 +664,14 @@
         }
     }
 
-    static class Activity extends ActivityContainer {
+    public static class Activity extends ActivityContainer {
 
         String name;
         String state;
         boolean visible;
         boolean frontOfTask;
         int procId = -1;
+        public boolean translucent;
 
         Activity(ActivityRecordProto proto) {
             super(proto.configurationContainer);
@@ -640,6 +682,7 @@
             if (proto.procId != 0) {
                 procId = proto.procId;
             }
+            translucent = proto.translucent;
         }
     }
 
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index e187eee..fcca246 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -510,6 +510,10 @@
                 && !hasDeviceFeature(FEATURE_EMBEDDED);
     }
 
+    protected boolean isWatch() {
+        return hasDeviceFeature(FEATURE_WATCH);
+    }
+
     protected boolean isTablet() {
         // Larger than approx 7" tablets
         return mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600;
@@ -1004,6 +1008,49 @@
         }.assertValidator("***Waiting for activity destroyed");
     }
 
+    void assertLifecycleCounts(ComponentName activityName, LogSeparator logSeparator,
+            int createCount, int startCount, int resumeCount, int pauseCount, int stopCount,
+            int destroyCount, int configurationChangeCount) {
+        new RetryValidator() {
+            @Override
+            protected String validate() {
+                final ActivityLifecycleCounts lifecycleCounts =
+                        new ActivityLifecycleCounts(activityName, logSeparator);
+                final String logTag = getLogTag(activityName);
+                if (createCount != lifecycleCounts.mCreateCount) {
+                    return logTag + " has been created " + lifecycleCounts.mCreateCount
+                            + " time(s), expecting " + createCount;
+                }
+                if (startCount != lifecycleCounts.mStartCount) {
+                    return logTag + " has been started " + lifecycleCounts.mStartCount
+                            + " time(s), expecting " + startCount;
+                }
+                if (resumeCount != lifecycleCounts.mResumeCount) {
+                    return logTag + " has been resumed " + lifecycleCounts.mResumeCount
+                            + " time(s), expecting " + resumeCount;
+                }
+                if (pauseCount != lifecycleCounts.mPauseCount) {
+                    return logTag + " has been paused " + lifecycleCounts.mPauseCount
+                            + " time(s), expecting " + pauseCount;
+                }
+                if (stopCount != lifecycleCounts.mStopCount) {
+                    return logTag + " has been stopped " + lifecycleCounts.mStopCount
+                            + " time(s), expecting " + stopCount;
+                }
+                if (destroyCount != lifecycleCounts.mDestroyCount) {
+                    return logTag + " has been destroyed " + lifecycleCounts.mDestroyCount
+                            + " time(s), expecting " + destroyCount;
+                }
+                if (configurationChangeCount != lifecycleCounts.mConfigurationChangedCount) {
+                    return logTag + " has received config changes "
+                            + lifecycleCounts.mConfigurationChangedCount
+                            + " time(s), expecting " + configurationChangeCount;
+                }
+                return null;
+            }
+        }.assertValidator("***Waiting for activity lifecycle counts");
+    }
+
     void assertSingleLaunch(ComponentName activityName, LogSeparator logSeparator) {
         new ActivityLifecycleCountsValidator(activityName, logSeparator, 1 /* createCount */,
                 1 /* startCount */, 1 /* resumeCount */, 0 /* pauseCount */, 0 /* stopCount */,
@@ -1329,6 +1376,10 @@
             return mTargetActivity;
         }
 
+        public boolean isTargetActivityTranslucent() {
+            return mAmWmState.getAmState().isActivityTranslucent(mTargetActivity);
+        }
+
         public LaunchActivityBuilder setTargetActivity(ComponentName targetActivity) {
             mTargetActivity = targetActivity;
             return this;
diff --git a/tests/framework/base/windowmanager/AndroidTest.xml b/tests/framework/base/windowmanager/AndroidTest.xml
index 624d4e6..337ada0 100644
--- a/tests/framework/base/windowmanager/AndroidTest.xml
+++ b/tests/framework/base/windowmanager/AndroidTest.xml
@@ -22,11 +22,16 @@
         <option name="test-file-name" value="CtsWindowManagerDeviceTestCases.apk"/>
         <option name="test-file-name" value="CtsDragAndDropSourceApp.apk"/>
         <option name="test-file-name" value="CtsDragAndDropTargetApp.apk"/>
-        <option name="test-file-name" value="CtsDragAndDropTargetAppSdk23.apk"/>
         <option name="test-file-name" value="CtsDeviceAlertWindowTestApp.apk"/>
-        <option name="test-file-name" value="CtsDeviceAlertWindowTestAppSdk25.apk"/>
         <option name="test-file-name" value="CtsAlertWindowService.apk"/>
     </target_preparer>
+    <!-- Some older apk cannot be installed as instant, so we force them full mode -->
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true"/>
+        <option name="force-install-mode" value="FULL"/>
+        <option name="test-file-name" value="CtsDragAndDropTargetAppSdk23.apk"/>
+        <option name="test-file-name" value="CtsDeviceAlertWindowTestAppSdk25.apk"/>
+    </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="android.server.cts.wm"/>
         <option name="runtime-hint" value="8m"/>
diff --git a/tests/framework/base/windowmanager/alertwindowapp/AndroidManifest.xml b/tests/framework/base/windowmanager/alertwindowapp/AndroidManifest.xml
index 446e2fa..00268da 100755
--- a/tests/framework/base/windowmanager/alertwindowapp/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/alertwindowapp/AndroidManifest.xml
@@ -17,7 +17,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-          package="android.server.wm.alertwindowapp">
+          package="android.server.wm.alertwindowapp"
+          android:targetSandboxVersion="2">
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
     <application android:label="CtsAlertWindow">
diff --git a/tests/framework/base/windowmanager/alertwindowservice/AndroidManifest.xml b/tests/framework/base/windowmanager/alertwindowservice/AndroidManifest.xml
index 76c30bd..48164b6 100644
--- a/tests/framework/base/windowmanager/alertwindowservice/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/alertwindowservice/AndroidManifest.xml
@@ -15,7 +15,8 @@
   ~ limitations under the License
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-       package="android.server.wm.alertwindowservice">
+       package="android.server.wm.alertwindowservice"
+       android:targetSandboxVersion="2">
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
     <application>
diff --git a/tests/framework/base/windowmanager/dndsourceapp/AndroidManifest.xml b/tests/framework/base/windowmanager/dndsourceapp/AndroidManifest.xml
index 4c8f0bb..e7b3453 100644
--- a/tests/framework/base/windowmanager/dndsourceapp/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/dndsourceapp/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.server.wm.dndsourceapp">
+        package="android.server.wm.dndsourceapp"
+        android:targetSandboxVersion="2">
     <application android:label="CtsDnDSource">
         <activity android:name="android.server.wm.dndsourceapp.DragSource">
             <intent-filter>
diff --git a/tests/framework/base/windowmanager/dndtargetapp/AndroidManifest.xml b/tests/framework/base/windowmanager/dndtargetapp/AndroidManifest.xml
index 33c7a0f..09a0bc9 100644
--- a/tests/framework/base/windowmanager/dndtargetapp/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/dndtargetapp/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.server.wm.dndtargetapp">
+        package="android.server.wm.dndtargetapp"
+        android:targetSandboxVersion="2">
     <application android:label="CtsDnDTarget">
         <activity android:name="android.server.wm.dndtargetapp.DropTarget">
             <intent-filter>
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
index 2da6bf0..5d087a7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
@@ -39,6 +39,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.server.wm.alertwindowservice.AlertWindowService;
 import android.support.test.InstrumentationRegistry;
@@ -113,6 +114,7 @@
     }
 
     @Test
+    @AppModeFull(reason = "Uses apps targeting older SDK")
     public void testAlertWindowOomAdj() throws Exception {
         // Alert windows are always hidden when running in VR.
         if (isRunningInVR()) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
index ae9c5b5..3ab7c198 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.server.am.ActivityManagerTestBase;
 import android.server.am.WaitForValidActivityState;
@@ -44,6 +45,7 @@
  *     atest CtsWindowManagerDeviceTestCases:AlertWindowsTests
  */
 @Presubmit
+@AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
 public class AlertWindowsTests extends ActivityManagerTestBase {
 
     // From WindowManager.java
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
index 0cc2ac8..5d26234 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
@@ -37,6 +37,7 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.os.RemoteException;
+import android.platform.test.annotations.AppModeFull;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
@@ -54,6 +55,7 @@
  * Run: cts/tests/framework/base/activitymanager/util/run-test CtsWindowManagerDeviceTestCases android.server.wm.CrossAppDragAndDropTests
  */
 @Presubmit
+@AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
 public class CrossAppDragAndDropTests {
     private static final String TAG = "CrossAppDragAndDrop";
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index 7e08bff..cc8eba0 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -36,6 +36,7 @@
 
 import android.content.ComponentName;
 import android.graphics.Rect;
+import android.platform.test.annotations.AppModeFull;
 import android.server.am.WaitForValidActivityState;
 import android.server.am.WindowManagerState;
 import android.server.am.WindowManagerState.WindowState;
@@ -54,6 +55,7 @@
  *
  * TODO: Consolidate this class with {@link ParentChildTestBase}.
  */
+@AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
 public class DialogFrameTests extends ParentChildTestBase<DialogFrameTestActivity> {
 
     private static final ComponentName DIALOG_FRAME_TEST_ACTIVITY = new ComponentName(
diff --git a/tests/inputmethod/Android.mk b/tests/inputmethod/Android.mk
index e0c7a62..0d11efa 100644
--- a/tests/inputmethod/Android.mk
+++ b/tests/inputmethod/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_MULTILIB := both
 
diff --git a/tests/inputmethod/AndroidManifest.xml b/tests/inputmethod/AndroidManifest.xml
index a5bc532..b9c0ef4 100644
--- a/tests/inputmethod/AndroidManifest.xml
+++ b/tests/inputmethod/AndroidManifest.xml
@@ -16,7 +16,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.view.inputmethod.cts">
+    package="android.view.inputmethod.cts"
+    android:targetSandboxVersion="2">
 
     <application
         android:label="CtsInputMethodTestCases"
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index f69fff5..f749065 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -28,6 +28,10 @@
         -->
         <option name="test-file-name" value="CtsInputMethodTestCases.apk" />
     </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="cmd input_method set-bind-instant-service-allowed true" />
+        <option name="teardown-command" value="cmd input_method set-bind-instant-service-allowed false" />
+    </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.view.inputmethod.cts" />
         <option name="runtime-hint" value="1m0s" />
diff --git a/tests/inputmethod/mockime/Android.mk b/tests/inputmethod/mockime/Android.mk
index fee0536..5cfed53 100644
--- a/tests/inputmethod/mockime/Android.mk
+++ b/tests/inputmethod/mockime/Android.mk
@@ -21,9 +21,6 @@
 
 LOCAL_SDK_VERSION := current
 
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_JAVA_LIBRARIES := junit
 LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
index b923c66..8400c53 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
@@ -18,7 +18,6 @@
 
 import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS;
 import static android.content.Intent.FLAG_RECEIVER_FOREGROUND;
-import static android.view.inputmethod.cts.util.TestUtils.runOnMainSync;
 import static android.view.inputmethod.cts.util.TestUtils.waitOnMainUntil;
 
 import static org.junit.Assert.assertFalse;
@@ -30,6 +29,7 @@
 import android.content.Context;
 import android.content.Intent;
 import androidx.annotation.NonNull;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -165,6 +165,7 @@
         }).collect(Collectors.joining(", ")) + "]";
     }
 
+    @AppModeFull(reason = "Instant apps cannot rely on ACTION_CLOSE_SYSTEM_DIALOGS")
     @Test
     public void testShowInputMethodPicker() throws Exception {
         TestActivity.startSync(activity -> {
diff --git a/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/DalvikTest.java b/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/DalvikTest.java
index 8d33687..324df40 100644
--- a/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/DalvikTest.java
+++ b/tests/jdwp/runner/host-side/src/com/android/compatibility/testtype/DalvikTest.java
@@ -26,6 +26,7 @@
 import com.android.tradefed.config.OptionCopier;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.ITestInvocationListener;
 import com.android.tradefed.result.TestDescription;
 import com.android.tradefed.testtype.IAbi;
@@ -321,6 +322,7 @@
             if (!mDevice.pushFile(tmpExcludeFile, EXCLUDE_FILE)) {
                 Log.logAndDisplay(LogLevel.ERROR, TAG, "Couldn't push file: " + tmpExcludeFile);
             } else {
+                CLog.d("exclude-filter-file: %s", safeReadContentFromFile(tmpExcludeFile));
                 // If sucessfully pushed then add it as a filter.
                 excludeFile = String.format("--exclude-filter-file=%s", EXCLUDE_FILE);
             }
@@ -340,6 +342,7 @@
             if (!mDevice.pushFile(mIncludeTestFile, INCLUDE_FILE)) {
                 Log.logAndDisplay(LogLevel.ERROR, TAG, "Couldn't push file: " + path);
             } else {
+                CLog.d("include-filter-file: %s", safeReadContentFromFile(mIncludeTestFile));
                 // If sucessfully pushed then add it as a filter.
                 includeFile = String.format("--include-filter-file=%s", INCLUDE_FILE);
             }
@@ -398,11 +401,9 @@
                     if (tag.equals(START_RUN)) {
                         listener.testRunStarted(mRunName, Integer.parseInt(parts[1]));
                         Log.logAndDisplay(LogLevel.INFO, TAG, command);
-                        Log.logAndDisplay(LogLevel.INFO, TAG, line);
                     } else if (tag.equals(END_RUN)) {
                         listener.testRunEnded(Integer.parseInt(parts[1]),
                                 Collections.<String, String>emptyMap());
-                        Log.logAndDisplay(LogLevel.INFO, TAG, line);
                     } else if (tag.equals(START_TEST)) {
                         test = getTestDescription(parts[1]);
                         listener.testStarted(test);
@@ -411,9 +412,9 @@
                     } else if (tag.equals(END_TEST)) {
                         listener.testEnded(getTestDescription(parts[1]),
                                 Collections.<String, String>emptyMap());
-                    } else {
-                        Log.logAndDisplay(LogLevel.INFO, TAG, line);
                     }
+                    // Always log the output for debugging
+                    CLog.d(line);
                 }
             }
 
@@ -561,4 +562,13 @@
             return name.startsWith(mName) && name.endsWith(EXPECTATIONS_EXT);
         }
     }
+
+    private String safeReadContentFromFile(File file) {
+        try {
+            return FileUtil.readStringFromFile(file);
+        } catch (IOException e) {
+            CLog.e(e);
+            return null;
+        }
+    }
 }
diff --git a/tests/mocking/inline/AndroidTest.xml b/tests/mocking/inline/AndroidTest.xml
index bfade92..7158dcb 100644
--- a/tests/mocking/inline/AndroidTest.xml
+++ b/tests/mocking/inline/AndroidTest.xml
@@ -27,4 +27,8 @@
         <option name="package" value="android.inline.mocking.cts" />
         <option name="runtime-hint" value="30s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/tests/signature/api-check/hidden-api-blacklist-debug-class/Android.mk
similarity index 62%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to tests/signature/api-check/hidden-api-blacklist-debug-class/Android.mk
index e6ee38f..7f6d5b6 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/tests/signature/api-check/hidden-api-blacklist-debug-class/Android.mk
@@ -15,16 +15,8 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
-LOCAL_MODULE_TAGS := optional
+LOCAL_PACKAGE_NAME := CtsHiddenApiBlacklistDebugClassTestCases
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
-
-include $(BUILD_CTS_PACKAGE)
+LOCAL_SIGNATURE_API_FILES := blacklist.api dark_greylist.api
+LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
new file mode 100644
index 0000000..8586df6
--- /dev/null
+++ b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.signature.cts.api.hiddenapi_blacklist_debug_class">
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+
+    <application/>
+
+    <instrumentation
+        android:name="repackaged.android.test.InstrumentationTestRunner"
+        android:targetPackage="android.signature.cts.api.hiddenapi_blacklist_debug_class"
+        android:label="Hidden API Blacklist Test with Debug Class Exempt"/>
+</manifest>
diff --git a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidTest.xml
similarity index 61%
copy from tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
copy to tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidTest.xml
index 478c7c2..e58c362 100644
--- a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidTest.xml
@@ -17,19 +17,22 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="systems" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <!-- Whitelist all APIs before running the test, then reset this afterwards. The test
-             is intended to verify the behaviour when all APIs are whitelisted. -->
-        <option name="run-command" value="settings put global hidden_api_blacklist_exemptions L" />
-        <option name="teardown-command" value="settings delete global hidden_api_blacklist_exemptions" />
+        <option name="run-command" value="mkdir -p /data/local/tmp/signature-test" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="blacklist.api->/data/local/tmp/signature-test/blacklist.api" />
+        <option name="push" value="dark_greylist.api->/data/local/tmp/signature-test/dark_greylist.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiWhitelistTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiBlacklistDebugClassTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.whitelist" />
+        <option name="package" value="android.signature.cts.api.hiddenapi_blacklist_debug_class" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="class" value="android.signature.cts.api.KillswitchTest" />
-        <option name="runtime-hint" value="60s" />
+        <option name="class" value="android.signature.cts.api.DebugClassHiddenApiTest" />
+        <option name="instrumentation-arg" key="hidden-api-files" value="blacklist.api,dark_greylist.api" />
+        <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/tests/signature/api-check/hidden-api-killswitch-debug-class/Android.mk
similarity index 94%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to tests/signature/api-check/hidden-api-killswitch-debug-class/Android.mk
index e6ee38f..7423448 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/Android.mk
@@ -15,7 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
+LOCAL_PACKAGE_NAME := CtsHiddenApiKillswitchDebugClassTestCases
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_MULTILIB := both
diff --git a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
similarity index 83%
copy from tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
copy to tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
index 2e990a1..1bd686b 100644
--- a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
@@ -16,11 +16,11 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.killswitch">
+          package="android.signature.cts.api.killswitch_debug_class">
 
     <application android:debuggable="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.killswitch"
-                     android:label="Hidden API Killswitch Test"/>
+                     android:targetPackage="android.signature.cts.api.killswitch_debug_class"
+                     android:label="Hidden API Debuggable Class Killswitch Test"/>
 </manifest>
diff --git a/tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
similarity index 69%
copy from tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml
copy to tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
index 35bf729..837dde8 100644
--- a/tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
@@ -16,20 +16,18 @@
 <configuration description="Config for CTS Hidden API Signature test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="systems" />
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <!-- Enable the killswitch before running the test, then disable it afterwards. The test
-             is intended to verify the behaviour when the killswitch is enabled. -->
-        <option name="run-command" value="settings put global hidden_api_blacklist_exemptions \*" />
-        <option name="teardown-command" value="settings delete global hidden_api_blacklist_exemptions" />
-    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiKillswitchTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiKillswitchDebugClassTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.killswitch" />
+        <option name="package" value="android.signature.cts.api.killswitch_debug_class" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="class" value="android.signature.cts.api.KillswitchTest" />
+        <option name="class" value="android.signature.cts.api.DebugClassKillswitchTest" />
         <option name="runtime-hint" value="60s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/tests/signature/api-check/hidden-api-killswitch-whitelist/Android.mk
similarity index 94%
rename from tests/signature/api-check/hidden-api-whitelist/Android.mk
rename to tests/signature/api-check/hidden-api-killswitch-whitelist/Android.mk
index e6ee38f..9364286 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/tests/signature/api-check/hidden-api-killswitch-whitelist/Android.mk
@@ -15,7 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
+LOCAL_PACKAGE_NAME := CtsHiddenApiKillswitchWhitelistTestCases
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_MULTILIB := both
diff --git a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
similarity index 84%
copy from tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
copy to tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
index 2e990a1..5b023af 100644
--- a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
@@ -16,11 +16,11 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.killswitch">
+          package="android.signature.cts.api.killswitch_whitelist">
 
     <application android:debuggable="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.killswitch"
-                     android:label="Hidden API Killswitch Test"/>
+                     android:targetPackage="android.signature.cts.api.killswitch_whitelist"
+                     android:label="Hidden API Killswitch Whitelist Test"/>
 </manifest>
diff --git a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidTest.xml
similarity index 78%
rename from tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
rename to tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidTest.xml
index 478c7c2..720f16ff 100644
--- a/tests/signature/api-check/hidden-api-whitelist/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidTest.xml
@@ -24,12 +24,16 @@
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiWhitelistTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiKillswitchWhitelistTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.whitelist" />
+        <option name="package" value="android.signature.cts.api.killswitch_whitelist" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="class" value="android.signature.cts.api.KillswitchTest" />
+        <option name="class" value="android.signature.cts.api.WhitelistKillswitchTest" />
         <option name="runtime-hint" value="60s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-whitelist/Android.mk b/tests/signature/api-check/hidden-api-killswitch-wildcard/Android.mk
similarity index 94%
copy from tests/signature/api-check/hidden-api-whitelist/Android.mk
copy to tests/signature/api-check/hidden-api-killswitch-wildcard/Android.mk
index e6ee38f..2274762 100644
--- a/tests/signature/api-check/hidden-api-whitelist/Android.mk
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/Android.mk
@@ -15,7 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiWhitelistTestCases
+LOCAL_PACKAGE_NAME := CtsHiddenApiKillswitchWildcardTestCases
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_MULTILIB := both
diff --git a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
similarity index 84%
rename from tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
rename to tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
index 2e990a1..68f3acf 100644
--- a/tests/signature/api-check/hidden-api-killswitch/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
@@ -16,11 +16,11 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.killswitch">
+          package="android.signature.cts.api.killswitch_wildcard">
 
     <application android:debuggable="true"/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.killswitch"
-                     android:label="Hidden API Killswitch Test"/>
+                     android:targetPackage="android.signature.cts.api.killswitch_wildcard"
+                     android:label="Hidden API Wildcard Killswitch Test"/>
 </manifest>
diff --git a/tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
similarity index 81%
rename from tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml
rename to tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
index 35bf729..bb726bb 100644
--- a/tests/signature/api-check/hidden-api-killswitch/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
@@ -24,12 +24,16 @@
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsHiddenApiKillswitchTestCases.apk" />
+        <option name="test-file-name" value="CtsHiddenApiKillswitchWildcardTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api.killswitch" />
+        <option name="package" value="android.signature.cts.api.killswitch_wildcard" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="class" value="android.signature.cts.api.KillswitchTest" />
+        <option name="class" value="android.signature.cts.api.WildcardKillswitchTest" />
         <option name="runtime-hint" value="60s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/signature/api-check/hidden-api-killswitch/Android.mk b/tests/signature/api-check/hidden-api-killswitch/Android.mk
deleted file mode 100644
index 33afcff..0000000
--- a/tests/signature/api-check/hidden-api-killswitch/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsHiddenApiKillswitchTestCases
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MULTILIB := both
-LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker libclassdescriptors
-LOCAL_NDK_STL_VARIANT := c++_static
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/signature/api-check/hidden-api-whitelist/AndroidManifest.xml b/tests/signature/api-check/hidden-api-whitelist/AndroidManifest.xml
deleted file mode 100644
index f00c60a..0000000
--- a/tests/signature/api-check/hidden-api-whitelist/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api.whitelist">
-
-    <application android:debuggable="true"/>
-
-    <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api.whitelist"
-                     android:label="Hidden API Whitelist Test"/>
-</manifest>
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/KillswitchTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java
similarity index 78%
rename from tests/signature/api-check/src/java/android/signature/cts/api/KillswitchTest.java
rename to tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java
index 2309f55..17a5b78 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/KillswitchTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java
@@ -16,6 +16,7 @@
 
 package android.signature.cts.api;
 
+import android.os.Bundle;
 import android.provider.Settings;
 import android.signature.cts.DexApiDocumentParser;
 import android.signature.cts.DexField;
@@ -23,29 +24,26 @@
 import android.signature.cts.DexMemberChecker;
 import android.signature.cts.DexMethod;
 import android.signature.cts.FailureType;
+import repackaged.android.test.InstrumentationTestRunner;
 
-public class KillswitchTest extends AbstractApiTest {
+public abstract class BaseKillswitchTest extends AbstractApiTest {
 
-    private String mExemptions;
+    protected String mErrorMessageAppendix;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         DexMemberChecker.init();
-        // precondition check: make sure global setting has been configured properly.
-        // This should be done via an adb command, configured in AndroidTest.xml.
-        mExemptions = Settings.Global.getString(
-            getInstrumentation().getContext().getContentResolver(),
-            Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
-        assertTrue("Global setting " + Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS,
-                "*".equals(mExemptions) || "L".equals(mExemptions));
     }
 
-    private String errorMessageAppendix() {
-        return " when global setting hidden_api_blacklist_exemptions is set to " + mExemptions;
+    protected String getGlobalExemptions() {
+      return Settings.Global.getString(
+          getInstrumentation().getContext().getContentResolver(),
+          Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
     }
 
-    public void testKillswitch() {
+    // Test shared by all the subclasses.
+    public void testKillswitchMechanism() {
         runWithTestResultObserver(resultObserver -> {
             DexMemberChecker.Observer observer = new DexMemberChecker.Observer() {
                 @Override
@@ -55,7 +53,7 @@
                                 FailureType.MISSING_CLASS,
                                 member.toString(),
                                 "Class from boot classpath is not accessible"
-                                        + errorMessageAppendix());
+                                        + mErrorMessageAppendix);
                     }
                 }
 
@@ -66,7 +64,7 @@
                                 FailureType.MISSING_FIELD,
                                 field.toString(),
                                 "Field from boot classpath is not accessible via reflection"
-                                        + errorMessageAppendix());
+                                        + mErrorMessageAppendix);
                     }
                 }
 
@@ -77,7 +75,7 @@
                                 FailureType.MISSING_FIELD,
                                 field.toString(),
                                 "Field from boot classpath is not accessible via JNI"
-                                        + errorMessageAppendix());
+                                        + mErrorMessageAppendix);
                     }
                 }
 
@@ -93,7 +91,7 @@
                                 FailureType.MISSING_METHOD,
                                 method.toString(),
                                 "Method from boot classpath is not accessible via reflection"
-                                        + errorMessageAppendix());
+                                        + mErrorMessageAppendix);
                     }
                 }
 
@@ -104,7 +102,7 @@
                                 FailureType.MISSING_METHOD,
                                 method.toString(),
                                 "Method from boot classpath is not accessible via JNI"
-                                        + errorMessageAppendix());
+                                        + mErrorMessageAppendix);
                     }
                 }
 
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java
new file mode 100644
index 0000000..8168f08
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api;
+
+import android.signature.cts.DexMemberChecker;
+
+public class DebugClassHiddenApiTest extends HiddenApiTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Try to exempt DexMemberChecker class from hidden API checks.
+        // This should fail as this process is not debuggable.
+        assertFalse(DexMemberChecker.requestExemptionFromHiddenApiChecks());
+    }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassKillswitchTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassKillswitchTest.java
new file mode 100644
index 0000000..7a5e900
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassKillswitchTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api;
+
+import android.signature.cts.DexMemberChecker;
+
+public class DebugClassKillswitchTest extends BaseKillswitchTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mErrorMessageAppendix = " to exempted DexMemberChecker class";
+
+        // Exempt DexMemberChecker class from hidden API checks.
+        assertTrue(DexMemberChecker.requestExemptionFromHiddenApiChecks());
+    }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
index f04f476..ba8e8c5 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
@@ -49,6 +49,12 @@
         hiddenApiFiles = getCommaSeparatedList(instrumentationArgs, "hidden-api-files");
     }
 
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        DexMemberChecker.init();
+    }
+
     /**
      * Tests that the device does not expose APIs on the provided lists of
      * DEX signatures.
@@ -56,7 +62,6 @@
      * Will check the entire API, and then report the complete list of failures
      */
     public void testSignature() {
-        DexMemberChecker.init();
         runWithTestResultObserver(resultObserver -> {
             DexMemberChecker.Observer observer = new DexMemberChecker.Observer() {
                 @Override
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/WhitelistKillswitchTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/WhitelistKillswitchTest.java
new file mode 100644
index 0000000..8eade1d
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/WhitelistKillswitchTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api;
+
+import android.signature.cts.DexMemberChecker;
+
+public class WhitelistKillswitchTest extends BaseKillswitchTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        String exemptions = getGlobalExemptions();
+        mErrorMessageAppendix = " when global setting hidden_api_blacklist_exemptions is "
+            + "\"" + exemptions + "\"";
+
+        // precondition check: make sure global setting has been configured properly.
+        // This should be done via an adb command, configured in AndroidTest.xml.
+        assertEquals("L", exemptions);
+    }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/WildcardKillswitchTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/WildcardKillswitchTest.java
new file mode 100644
index 0000000..32d352fe
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/WildcardKillswitchTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api;
+
+import android.signature.cts.DexMemberChecker;
+
+public class WildcardKillswitchTest extends BaseKillswitchTest {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        String exemptions = getGlobalExemptions();
+        mErrorMessageAppendix = " when global setting hidden_api_blacklist_exemptions is "
+            + "\"" + exemptions + "\"";
+
+        // precondition check: make sure global setting has been configured properly.
+        // This should be done via an adb command, configured in AndroidTest.xml.
+        assertEquals("*", exemptions);
+    }
+}
diff --git a/tests/signature/runSignatureTests.sh b/tests/signature/runSignatureTests.sh
index e5664fb..f8ec3d1 100755
--- a/tests/signature/runSignatureTests.sh
+++ b/tests/signature/runSignatureTests.sh
@@ -27,8 +27,11 @@
 
 CtsHiddenApiBlacklistCurrentApiTestCases
 CtsHiddenApiBlacklistApi27TestCases
-CtsHiddenApiKillswitchTestCases
-CtsHiddenApiWhitelistTestCases
+CtsHiddenApiBlacklistDebugClassTestCases
+
+CtsHiddenApiKillswitchWildcardTestCases
+CtsHiddenApiKillswitchWhitelistTestCases
+CtsHiddenApiKillswitchDebugClassTestCases
 "
 else
     PACKAGES=${1+"$@"}
diff --git a/tests/signature/src/android/signature/cts/DexMemberChecker.java b/tests/signature/src/android/signature/cts/DexMemberChecker.java
index b72cc35..edf4201 100644
--- a/tests/signature/src/android/signature/cts/DexMemberChecker.java
+++ b/tests/signature/src/android/signature/cts/DexMemberChecker.java
@@ -19,6 +19,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Executable;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.List;
 
@@ -36,6 +37,40 @@
         System.loadLibrary("cts_dexchecker");
     }
 
+    private static void call_VMDebug_allowHiddenApiReflectionFrom(Class<?> klass) throws Exception {
+      Method method = null;
+
+      try {
+        Class<?> vmdebug = Class.forName("dalvik.system.VMDebug");
+        method = vmdebug.getDeclaredMethod("allowHiddenApiReflectionFrom", Class.class);
+      } catch (Exception ex) {
+        // Could not find the method. Report the problem as a RuntimeException.
+        throw new RuntimeException(ex);
+      }
+
+      try {
+        method.invoke(null, klass);
+      } catch (InvocationTargetException ex) {
+        // Rethrow the original exception.
+        Throwable cause = ex.getCause();
+        // Please the compiler's 'throws' static analysis.
+        if (cause instanceof Exception) {
+          throw (Exception) cause;
+        } else {
+          throw (Error) cause;
+        }
+      }
+    }
+
+    public static boolean requestExemptionFromHiddenApiChecks() throws Exception {
+      try {
+        call_VMDebug_allowHiddenApiReflectionFrom(DexMemberChecker.class);
+        return true;
+      } catch (SecurityException ex) {
+        return false;
+      }
+    }
+
     public static void checkSingleMember(DexMember dexMember, DexMemberChecker.Observer observer) {
         Class<?> klass = findClass(dexMember);
         if (klass == null) {
diff --git a/tests/tests/accounts/Android.mk b/tests/tests/accounts/Android.mk
index 18ab37f..d816707 100644
--- a/tests/tests/accounts/Android.mk
+++ b/tests/tests/accounts/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    CtsAccountTestsCommon ctstestrunner
+    CtsAccountTestsCommon ctstestrunner platform-test-annotations
 
 LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
 
@@ -37,7 +37,7 @@
 LOCAL_SDK_VERSION := current
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_PACKAGE)
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/accounts/AndroidManifest.xml b/tests/tests/accounts/AndroidManifest.xml
index 73535bc..ec3d42d 100644
--- a/tests/tests/accounts/AndroidManifest.xml
+++ b/tests/tests/accounts/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.accounts.cts">
+        package="android.accounts.cts"
+        android:targetSandboxVersion="2">
     <uses-sdk android:minSdkVersion="1"
           android:targetSdkVersion="26"/>
 
diff --git a/tests/tests/accounts/AndroidTest.xml b/tests/tests/accounts/AndroidTest.xml
index 77118d7..e0a3ae9 100644
--- a/tests/tests/accounts/AndroidTest.xml
+++ b/tests/tests/accounts/AndroidTest.xml
@@ -16,6 +16,10 @@
 <configuration description="Config for CTS Accounts test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="cmd account set-bind-instant-service-allowed true" />
+        <option name="teardown-command" value="cmd account set-bind-instant-service-allowed false" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsUnaffiliatedAccountAuthenticators.apk" />
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
index 924b378..9428279 100644
--- a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
@@ -38,7 +38,7 @@
 LOCAL_PACKAGE_NAME := CtsUnaffiliatedAccountAuthenticators
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml
index 642b3d8..3a0b025 100644
--- a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.accounts.cts.unaffiliated">
+        package="android.accounts.cts.unaffiliated"
+        android:targetSandboxVersion="2">
     <uses-sdk android:minSdkVersion="1"
           android:targetSdkVersion="26"/>
 
diff --git a/tests/tests/accounts/src/android/accounts/cts/AbstractAuthenticatorTests.java b/tests/tests/accounts/src/android/accounts/cts/AbstractAuthenticatorTests.java
index 725e7a5..1b4f873 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AbstractAuthenticatorTests.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AbstractAuthenticatorTests.java
@@ -29,6 +29,7 @@
 import android.content.ContentResolver;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 
 import java.io.IOException;
@@ -60,7 +61,10 @@
     }
 
     public void tearDown() throws RemoteException {
-        mProviderClient.release();
+        if (mProviderClient != null) {
+            // mProviderClient is null in case of instant test
+            mProviderClient.release();
+        }
     }
 
     /**
@@ -139,6 +143,7 @@
      * Tests finishSession default implementation with default startAddAccountSession.
      * Only account name and account type should be returned as a bundle.
      */
+    @AppModeFull
     public void testFinishSessionAndStartAddAccountSessionDefaultImpl()
             throws OperationCanceledException, AuthenticatorException, IOException,
             RemoteException {
@@ -208,6 +213,7 @@
      * Tests finishSession default implementation with default startUpdateCredentialsSession.
      * Only account name and account type should be returned as a bundle.
      */
+    @AppModeFull
     public void testFinishSessionAndStartUpdateCredentialsSessionDefaultImpl()
             throws OperationCanceledException, AuthenticatorException, IOException,
             RemoteException {
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index c940c3f..4db2fd6 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -35,6 +35,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.StrictMode;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.test.ActivityInstrumentationTestCase2;
 
@@ -568,6 +569,7 @@
     /**
      * Test addAccountExplicitly(), renameAccount() and removeAccount().
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyAndRemoveAccount() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -593,6 +595,7 @@
     /**
      * Test addAccountExplicitly(), renameAccount() and removeAccount().
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyAndRemoveAccountWithNewApi() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -624,6 +627,7 @@
      * Test addAccountExplicitly(), renameAccount() and removeAccount() calling
      * into default implementations.
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyAndRemoveAccountWithDefaultImpl() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -648,6 +652,7 @@
     /**
      * Test addAccountExplicitly(), renameAccount() and removeAccount().
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyAndRemoveAccountWithDeprecatedApi() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -672,6 +677,7 @@
     /**
      * Test addAccountExplicitly() and removeAccountExplictly().
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyAndRemoveAccountExplicitly() {
         final int expectedAccountsCount = getAccountsCount();
 
@@ -694,6 +700,7 @@
     /**
      * Test updates to account visibility.
      */
+    @AppModeFull(reason = "The methods requires the caller to match signature with authenticator.")
     public void testSetAccountVisibility()
             throws IOException, AuthenticatorException, OperationCanceledException {
         am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
@@ -716,6 +723,7 @@
     /**
      * Test updates to account visibility for authenticator package.
      */
+    @AppModeFull(reason = "The methods requires the caller to match signature with authenticator.")
     public void testSetAccountVisibilityForPrivilegedPackage()
             throws IOException, AuthenticatorException, OperationCanceledException {
         am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
@@ -739,6 +747,7 @@
     /**
      * Test getPackagesAndVisibilityForAccount() method.
      */
+    @AppModeFull(reason = "The methods requires the caller to match signature with authenticator.")
     public void testGetPackagesAndVisibilityForAccount()
             throws IOException, AuthenticatorException, OperationCanceledException {
         am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
@@ -760,6 +769,7 @@
      * Test addAccountExplicitly(), setAccountVisibility() , getAccountVisibility(), and
      * removeAccount().
      */
+    @AppModeFull(reason = "The methods are for sign-up wizards associated with authenticators.")
     public void testAddAccountExplicitlyWithVisibility()
             throws IOException, AuthenticatorException, OperationCanceledException {
         Map<String, Integer> visibility = new HashMap<>();
@@ -795,6 +805,7 @@
     /**
      * Test testGetAccountsAndVisibilityForPackage(), getAccountsByTypeForPackage() methods.
      */
+    @AppModeFull(reason = "The methods requires the caller to match signature with authenticator.")
     public void testGetAccountsAndVisibilityForPackage() {
         am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */, null);
         am.addAccountExplicitly(ACCOUNT_SAME_TYPE, ACCOUNT_PASSWORD, null /* userData */, null);
@@ -852,6 +863,7 @@
      * Test checks order of accounts returned by getAccounts...().
      * Accounts should be grouped by type.
      */
+    @AppModeFull(reason = "The methods requires the caller to match signature with authenticator.")
     public void testGetAccountsReturnedOrder() {
         Account account_1_1 = new Account("account_z", ACCOUNT_TYPE);
         Account account_1_2 = new Account("account_c", ACCOUNT_TYPE);
@@ -1682,6 +1694,9 @@
     /**
      * Tests the setting of lastAuthenticatedTime on adding account
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testLastAuthenticatedTimeAfterAddAccount() throws IOException,
             AuthenticatorException, OperationCanceledException {
         assertTrue(addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD) > 0);
@@ -1708,6 +1723,9 @@
      * Tests the setting of lastAuthenticatedTime on confirmCredentials being
      * successful.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testLastAuthenticatedTimeAfterConfirmCredentialsSuccess() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -1729,6 +1747,9 @@
      * Tests the setting of lastAuthenticatedTime on updateCredentials being
      * successful.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testLastAuthenticatedTimeAfterUpdateCredentialsSuccess() throws IOException,
             AuthenticatorException, OperationCanceledException {
 
@@ -1747,6 +1768,7 @@
     /**
      * LastAuthenticatedTime on setPassword should not be disturbed.
      */
+    @AppModeFull(reason = "setPassword should be called by authenticator.")
     public void testLastAuthenticatedTimeAfterSetPassword() throws IOException,
             AuthenticatorException, OperationCanceledException {
         long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
@@ -2428,6 +2450,9 @@
      * and return the final result which contains an encrypted session bundle,
      * account password and status token.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartAddAccountSessionIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         final String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@"
@@ -2458,6 +2483,9 @@
      * automatically. When no Activity is provided and authenticator requires
      * additional data from user, KEY_INTENT will be returned by AccountManager.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartAddAccountSessionWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         final String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@"
@@ -2532,6 +2560,9 @@
      * session bundle, account password and status token. Callback should be
      * triggered with the result regardless of a handled is provided or not.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartAddAccountSessionWithCallbackAndHandlerWithIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testStartAddAccountSessionWithCallbackAndHandlerWithIntervene(null /* handler */);
@@ -2545,6 +2576,9 @@
      * additional data from user, KEY_INTENT will be returned by AccountManager
      * in callback regardless of a handler is provided or not.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartAddAccountSessionWithCallbackAndHandlerWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testStartAddAccountSessionWithCallbackAndHandlerWithReturnIntent(null /* handler */);
@@ -2818,6 +2852,9 @@
      * and return the final result which contains an encrypted session bundle,
      * account password and status token.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartUpdateCredentialsSessionIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
@@ -2846,6 +2883,9 @@
      * started automatically. When no Activity is provided and authenticator requires
      * additional data from user, KEY_INTENT will be returned by AccountManager.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartUpdateCredentialsSessionWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
@@ -2918,6 +2958,9 @@
      * session bundle, account password and status token. Callback should be
      * triggered with the result regardless of a handler is provided or not.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartUpdateCredentialsSessionWithCallbackAndHandlerWithIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testStartUpdateCredentialsSessionWithCallbackAndHandlerWithIntervene(null /* handler */);
@@ -2931,6 +2974,9 @@
      * additional data from user, KEY_INTENT will be returned by AccountManager
      * in callback regardless of a handler is provided or not.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testStartUpdateCredentialsSessionWithCallbackAndHandlerWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testStartUpdateCredentialsSessionWithCallbackAndHandlerWithReturnIntent(null /* handler */);
@@ -3626,6 +3672,9 @@
      * provided by caller, the resolution intent will be started automatically.
      * A bundle containing account name and type will be returned.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testFinishSessionIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
@@ -3675,6 +3724,9 @@
      * will not be started automatically. A bundle containing KEY_INTENT will be
      * returned instead.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testFinishSessionWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         String accountName = Fixtures.PREFIX_NAME_INTERVENE + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
@@ -3789,6 +3841,9 @@
      * automatically. A bundle containing account name and type will be returned
      * via the callback regardless of if handler is provided or now.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testFinishSessionWithCallbackAndHandlerWithIntervene()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testFinishSessionWithCallbackAndHandlerWithIntervene(null /* handler */);
@@ -3803,6 +3858,9 @@
      * will not be started automatically. A bundle containing KEY_INTENT will be
      * returned instead via callback regardless of if handler is provided or not.
      */
+    // TODO: Either allow the system to see the activity from instant app,
+    // Or separate the authenticator and test app to allow the instant app mode test.
+    @AppModeFull
     public void testFinishSessionWithCallbackAndHandlerWithReturnIntent()
             throws IOException, AuthenticatorException, OperationCanceledException {
         testFinishSessionWithCallbackAndHandlerWithReturnIntent(null /* handler */);
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java
index f9418f0..ebd6a13 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java
@@ -29,6 +29,7 @@
 import android.content.ContentResolver;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 
 import java.io.IOException;
@@ -57,28 +58,11 @@
     private ContentProviderClient mProviderClient;
 
     @Override
-    public void setUp() throws Exception {
+    public void setUp() {
         SESSION_BUNDLE.putString(SESSION_DATA_NAME_1, SESSION_DATA_VALUE_1);
 
         // bind to the diagnostic service and set it up.
         mAccountManager = AccountManager.get(getContext());
-        ContentResolver resolver = getContext().getContentResolver();
-        mProviderClient = resolver.acquireContentProviderClient(
-                AuthenticatorContentProvider.AUTHORITY);
-        /*
-         * This will install a bunch of accounts on the device
-         * (see Fixtures.getFixtureAccountNames()).
-         */
-        mProviderClient.call(AuthenticatorContentProvider.METHOD_SETUP, null, null);
-    }
-
-    @Override
-    public void tearDown() throws RemoteException {
-        try {
-            mProviderClient.call(AuthenticatorContentProvider.METHOD_TEARDOWN, null, null);
-        } finally {
-            mProviderClient.release();
-        }
     }
 
     public void testNotifyAccountAuthenticated() {
@@ -288,8 +272,13 @@
      * authenticator.
      * An encrypted session bundle should always be returned without password.
      */
+    // TODO: Either allow instant app to expose content provider, or move the content provider
+    // out of the test app.
+    @AppModeFull
     public void testStartAddAccountSession() throws
             OperationCanceledException, AuthenticatorException, IOException, RemoteException {
+        setupAccounts();
+
         String accountName = Fixtures.PREFIX_NAME_SUCCESS + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
         Bundle options = createOptionsWithAccountName(accountName);
 
@@ -313,6 +302,7 @@
 
         // Validate returned data
         validateSessionBundleAndPasswordAndStatusTokenResult(result);
+        resetAccounts();
     }
 
     /**
@@ -320,8 +310,13 @@
      * the authenticator.
      * An encrypted session bundle should always be returned without password.
      */
+    // TODO: Either allow instant app to expose content provider, or move the content provider
+    // out of the test app.
+    @AppModeFull
     public void testStartUpdateCredentialsSession() throws
             OperationCanceledException, AuthenticatorException, IOException, RemoteException {
+        setupAccounts();
+
         String accountName = Fixtures.PREFIX_NAME_SUCCESS + "@" + Fixtures.SUFFIX_NAME_FIXTURE;
         Bundle options = createOptionsWithAccountName(accountName);
 
@@ -344,6 +339,7 @@
 
         // Validate returned data
         validateSessionBundleAndPasswordAndStatusTokenResult(result);
+        resetAccounts();
     }
 
     /**
@@ -446,6 +442,25 @@
         }
     }
 
+    private void setupAccounts() throws RemoteException {
+        ContentResolver resolver = getContext().getContentResolver();
+        mProviderClient = resolver.acquireContentProviderClient(
+                AuthenticatorContentProvider.AUTHORITY);
+        /*
+         * This will install a bunch of accounts on the device
+         * (see Fixtures.getFixtureAccountNames()).
+         */
+        mProviderClient.call(AuthenticatorContentProvider.METHOD_SETUP, null, null);
+    }
+
+    private void resetAccounts() throws RemoteException {
+        try {
+            mProviderClient.call(AuthenticatorContentProvider.METHOD_TEARDOWN, null, null);
+        } finally {
+            mProviderClient.release();
+        }
+    }
+
     private void validateStartAddAccountSessionParameters(Bundle inOpt)
             throws RemoteException {
         Bundle params = mProviderClient.call(AuthenticatorContentProvider.METHOD_GET, null, null);
@@ -488,4 +503,3 @@
                 result.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN));
     }
 }
-
diff --git a/tests/tests/app.usage/Android.mk b/tests/tests/app.usage/Android.mk
index 6ac0d63..eb22828 100644
--- a/tests/tests/app.usage/Android.mk
+++ b/tests/tests/app.usage/Android.mk
@@ -37,6 +37,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml
index 06cd092..9c4342f 100644
--- a/tests/tests/app.usage/AndroidManifest.xml
+++ b/tests/tests/app.usage/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.app.usage.cts">
+    package="android.app.usage.cts" android:targetSandboxVersion="2">
 
     <!-- We can't have the test framework turn off the keyguard, because that will
          prevent us from testing interactions with it.
@@ -29,8 +29,9 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
+    <application android:usesCleartextTraffic="true"
+            android:networkSecurityConfig="@xml/network_security_config">
+        <uses-library android:name="android.test.runner"/>
 
         <activity android:name=".Activities$ActivityOne" />
         <activity android:name=".Activities$ActivityTwo" />
@@ -48,4 +49,3 @@
     </instrumentation>
 
 </manifest>
-
diff --git a/tests/tests/app.usage/res/xml/network_security_config.xml b/tests/tests/app.usage/res/xml/network_security_config.xml
new file mode 100644
index 0000000..341cc7b
--- /dev/null
+++ b/tests/tests/app.usage/res/xml/network_security_config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<network-security-config>
+    <domain-config cleartextTrafficPermitted="true">
+        <domain includeSubdomains="true">www.265.com</domain>
+    </domain-config>
+</network-security-config>
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
index d503b12..fe8cd6e 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
@@ -32,10 +32,10 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.platform.test.annotations.AppModeFull;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
-
 import com.android.compatibility.common.util.SystemUtil;
 
 import java.io.FileInputStream;
@@ -342,6 +342,7 @@
         return "";
     }
 
+    @AppModeFull
     public void testDeviceSummary() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             if (!shouldTestThisNetworkType(i, MINUTE/2)) {
@@ -376,6 +377,7 @@
         }
     }
 
+    @AppModeFull
     public void testUserSummary() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             if (!shouldTestThisNetworkType(i, MINUTE/2)) {
@@ -410,6 +412,7 @@
         }
     }
 
+    @AppModeFull
     public void testAppSummary() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             if (!shouldTestThisNetworkType(i, MINUTE/2)) {
@@ -474,6 +477,7 @@
         }
     }
 
+    @AppModeFull
     public void testAppDetails() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             // Relatively large tolerance to accommodate for history bucket size.
@@ -516,6 +520,7 @@
         }
     }
 
+    @AppModeFull
     public void testUidDetails() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             // Relatively large tolerance to accommodate for history bucket size.
@@ -568,6 +573,7 @@
         }
     }
 
+    @AppModeFull
     public void testTagDetails() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             // Relatively large tolerance to accommodate for history bucket size.
@@ -673,6 +679,7 @@
                 bucket.getRxBytes(), bucket.getTxBytes()));
     }
 
+    @AppModeFull
     public void testUidTagStateDetails() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             // Relatively large tolerance to accommodate for history bucket size.
@@ -749,6 +756,7 @@
         }
     }
 
+    @AppModeFull
     public void testCallback() throws Exception {
         for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
             // Relatively large tolerance to accommodate for history bucket size.
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 5c55639..a793150 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -39,6 +39,7 @@
 import android.content.pm.PackageManager;
 import android.os.Parcel;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -49,6 +50,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseLongArray;
+import android.view.KeyEvent;
 
 import com.android.compatibility.common.util.AppStandbyUtils;
 
@@ -139,6 +141,7 @@
         }
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testOrderedActivityLaunchSequenceInEventLog() throws Exception {
         @SuppressWarnings("unchecked")
@@ -202,6 +205,7 @@
         }
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testAppLaunchCount() throws Exception {
         long endTime = System.currentTimeMillis();
@@ -228,13 +232,14 @@
         assertEquals(startingCount + 2, stats.getAppLaunchCount());
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testStandbyBucketChangeLog() throws Exception {
         final long startTime = System.currentTimeMillis();
         mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " rare");
 
         final long endTime = System.currentTimeMillis();
-        UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
+        UsageEvents events = mUsageStatsManager.queryEvents(startTime - 1_000, endTime + 1_000);
 
         boolean found = false;
         // Check all the events.
@@ -382,6 +387,7 @@
         assertEquals(events.hasNextEvent(), reparceledEvents.hasNextEvent());
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testPackageUsageStatsIntervals() throws Exception {
         final long beforeTime = System.currentTimeMillis();
@@ -444,6 +450,7 @@
         assertTrue(stats.isEmpty());
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testNotificationSeen() throws Exception {
         final long startTime = System.currentTimeMillis();
@@ -733,6 +740,7 @@
         }
     }
 
+    @AppModeFull // No usage events access in instant apps
     @Test
     public void testInteractiveEvents() throws Exception {
         final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
@@ -740,7 +748,7 @@
 
         // We need to start out with the screen on.
         if (!mUiDevice.isScreenOn()) {
-            mUiDevice.wakeUp();
+            pressWakeUp();
             SystemClock.sleep(1000);
         }
 
@@ -761,7 +769,7 @@
             SparseArray<AggrAllEventsData> baseAggr = getAggrEventData(0);
 
             // First test -- put device to sleep and make sure we see this event.
-            mUiDevice.sleep();
+            pressSleep();
 
             // Do we have one event, going in to non-interactive mode?
             events = waitForEventCount(INTERACTIVE_EVENTS, startTime, 1);
@@ -773,7 +781,7 @@
             // XXX need to wait a bit so we don't accidentally trigger double-power
             // to launch camera.  (SHOULD FIX HOW WE WAKEUP / SLEEP TO NOT USE POWER KEY)
             SystemClock.sleep(500);
-            mUiDevice.wakeUp();
+            pressWakeUp();
             events = waitForEventCount(INTERACTIVE_EVENTS, startTime, 2);
             assertEquals(Event.SCREEN_NON_INTERACTIVE, events.get(0).getEventType());
             assertEquals(Event.SCREEN_INTERACTIVE, events.get(1).getEventType());
@@ -803,7 +811,7 @@
 
         } finally {
             // Dismiss keyguard to get device back in its normal state.
-            mUiDevice.wakeUp();
+            pressWakeUp();
             mUiDevice.executeShellCommand("wm dismiss-keyguard");
         }
     }
@@ -838,4 +846,12 @@
         }
         fail("Should throw SecurityException");
     }
+
+    private void pressWakeUp() {
+        mUiDevice.pressKeyCode(KeyEvent.KEYCODE_WAKEUP);
+    }
+
+    private void pressSleep() {
+        mUiDevice.pressKeyCode(KeyEvent.KEYCODE_SLEEP);
+    }
 }
diff --git a/tests/tests/appwidget/Android.mk b/tests/tests/appwidget/Android.mk
index 4e3a218..ae33c1b 100644
--- a/tests/tests/appwidget/Android.mk
+++ b/tests/tests/appwidget/Android.mk
@@ -29,7 +29,8 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-target-minus-junit4 \
     ctstestrunner \
-    junit
+    junit \
+    compatibility-device-util
 
 LOCAL_JAVA_LIBRARIES := android.test.base.stubs
 
diff --git a/tests/tests/appwidget/src/android/appwidget/cts/RequestPinAppWidgetTest.java b/tests/tests/appwidget/src/android/appwidget/cts/RequestPinAppWidgetTest.java
index f015181..6a54e57 100644
--- a/tests/tests/appwidget/src/android/appwidget/cts/RequestPinAppWidgetTest.java
+++ b/tests/tests/appwidget/src/android/appwidget/cts/RequestPinAppWidgetTest.java
@@ -40,6 +40,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import com.android.compatibility.common.util.CddTest;
+
 @AppModeFull(reason = "Instant apps cannot provide or host app widgets")
 public class RequestPinAppWidgetTest extends AppWidgetTestCase {
 
@@ -59,6 +61,7 @@
         setLauncher(mDefaultLauncher);
     }
 
+    @CddTest(requirement="3.8.2/C-2-2")
     private void runPinWidgetTest(final String launcherPkg) throws Exception {
         setLauncher(launcherPkg + "/" + LAUNCHER_CLASS);
 
@@ -114,6 +117,7 @@
         runPinWidgetTest("android.appwidget.cts.packages.launcher2");
     }
 
+    @CddTest(requirement="3.8.2/C-2-1")
     public void verifyIsRequestPinAppWidgetSupported(String launcherPkg, boolean expectedSupport)
         throws Exception {
         setLauncher(launcherPkg + "/" + LAUNCHER_CLASS);
diff --git a/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java b/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
index 6af3020..a8320ff 100644
--- a/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
+++ b/tests/tests/background/src/android/app/cts/backgroundrestrictions/BroadcastsTest.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
@@ -82,6 +83,7 @@
      * Make sure "com.android.launcher.action.INSTALL_SHORTCUT" won't be delivered to a manifest
      * receiver, even if an intent is targeted to the component.
      */
+    @AppModeFull(reason = "Instant apps don't get to run in the background.")
     @Test
     @CddTest(requirement="3.5/C-0-6")
     public void testNonSupportedBroadcastsNotDelivered_manifestReceiver() throws Exception {
@@ -103,7 +105,7 @@
 
         AmUtils.waitForBroadcastIdle();
 
-        // This broadcast should be delivered.
+        // This broadcast should not be delivered.
         final String[] UNSUPPORTED_BROADCASTS = new String[]{
                 "com.android.launcher.action.INSTALL_SHORTCUT",
         };
diff --git a/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
index d9f144c..2dd0a81 100644
--- a/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
@@ -45,10 +45,16 @@
 
         // Request all application focuses and abandon them to ensure no active context is present
         // when test starts.
+        int[] activeTypes =  mManager.getActiveAppTypes();
         FocusOwnershipCallback owner = new FocusOwnershipCallback();
-        mManager.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, owner);
-        mManager.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND, owner);
-        mManager.abandonAppFocus(owner);
+        for (int i = 0; i < activeTypes.length; i++) {
+            mManager.requestAppFocus(activeTypes[i], owner);
+            owner.waitForOwnershipGrantAndAssert(DEFAULT_WAIT_TIMEOUT_MS, activeTypes[i]);
+            mManager.abandonAppFocus(owner, activeTypes[i]);
+            owner.waitForOwnershipLossAndAssert(
+                    DEFAULT_WAIT_TIMEOUT_MS, activeTypes[i]);
+        }
+
     }
 
     public void testSetActiveNullListener() throws Exception {
diff --git a/tests/tests/content/Android.mk b/tests/tests/content/Android.mk
index dc2c253..616f898 100644
--- a/tests/tests/content/Android.mk
+++ b/tests/tests/content/Android.mk
@@ -22,6 +22,9 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_USE_AAPT2 := true
 
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
 LOCAL_JNI_SHARED_LIBRARIES := libnativecursorwindow_jni libnativehelper_compat_libc++
 
 LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs android.test.mock
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java b/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
index 3ab43ee..4d5378c 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
@@ -25,6 +25,7 @@
 /**
  * Test {@link CursorWindowContentProvider} .
  */
+@SecurityTest
 public class ContentProviderCursorWindowTest extends AndroidTestCase {
     private static final String TAG = "ContentProviderCursorWindowTest";
 
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
index 2759a54..1dcee00 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
@@ -1640,10 +1640,10 @@
     }
 
     /**
-     * Test that enableWriteAheadLogging is not affected by app's journal mode/synchronous mode
-     * settings
+     * Test that enableWriteAheadLogging is not affected by app's journal mode setting,
+     * but app can still control synchronous mode.
      */
-    public void testEnableWalOverridesJournalModeSynchronousMode() {
+    public void testEnableWalOverridesJournalModeSyncModePreserved() {
         mDatabase.close();
         SQLiteDatabase.OpenParams params = new SQLiteDatabase.OpenParams.Builder()
                 .setJournalMode("DELETE").setSynchronousMode("OFF").build();
@@ -1657,7 +1657,7 @@
         String syncMode = DatabaseUtils
                 .stringForQuery(mDatabase, "PRAGMA synchronous", null);
 
-        assertEquals("1" /* NORMAL */, syncMode);
+        assertEquals("0" /* OFF */, syncMode);
     }
 
     /**
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
index 1ce3706..371d6b6 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.AssetManager;
@@ -1723,8 +1724,15 @@
                         }
                     }
                 } else {
-                    // Not decoding to HARDWARE, so we can save RAM in either case.
-                    assertTrue(byteCount < normalByteCount);
+                    // Not decoding to HARDWARE, but |normal| was. Again, if basi6a16
+                    // was decoded to 8888, which we can detect by looking at the color
+                    // space, no savings are possible.
+                    if (resId == R.raw.basi6a16 && !normal.getColorSpace().equals(
+                                ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB))) {
+                        assertEquals(normalByteCount, byteCount);
+                    } else {
+                        assertTrue(byteCount < normalByteCount);
+                    }
                 }
             }
         }
@@ -2209,6 +2217,18 @@
 
     @Test
     public void testWarpedDng() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        ActivityManager activityManager = (ActivityManager) context
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
+        activityManager.getMemoryInfo(info);
+
+        // Decoding this image requires a lot of memory. Only attempt if the
+        // device has a total memory of at least 2 Gigs.
+        if (info.totalMem < 2 * 1024 * 1024 * 1024) {
+            return;
+        }
+
         String name = "b78120086.dng";
         ImageDecoder.Source src = ImageDecoder.createSource(mRes.getAssets(), name);
         try {
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 69aec7e..cec2723 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -28,7 +28,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include <list>
+#include <queue>
 #include <string>
 #include <unordered_set>
 #include <vector>
@@ -41,9 +41,11 @@
 #if defined(__LP64__)
 static const std::string kSystemLibraryPath = "/system/lib64";
 static const std::string kVendorLibraryPath = "/vendor/lib64";
+static const std::string kProductLibraryPath = "/product/lib64";
 #else
 static const std::string kSystemLibraryPath = "/system/lib";
 static const std::string kVendorLibraryPath = "/vendor/lib";
+static const std::string kProductLibraryPath = "/product/lib";
 #endif
 
 // This is not the complete list - just a small subset
@@ -67,9 +69,9 @@
     "libvorbisidec.so",
   };
 
-static bool is_directory(const std::string& path) {
+static bool is_directory(const char* path) {
   struct stat sb;
-  if (stat(path.c_str(), &sb) != -1) {
+  if (stat(path, &sb) != -1) {
     return S_ISDIR(sb.st_mode);
   }
 
@@ -93,22 +95,19 @@
   return err.find("dlopen failed: \"" + library + "\" has unexpected e_machine: ") == 0;
 }
 
-static bool is_library_on_path(const std::vector<std::string>& library_search_paths,
+static bool is_library_on_path(const std::unordered_set<std::string>& library_search_paths,
                                const std::string& baselib,
                                const std::string& path) {
-  for (const auto& search_path : library_search_paths) {
-    if (search_path + "/" + baselib == path) {
-      return true;
-    }
-  }
-  return false;
+  std::string tail = '/' + baselib;
+  if (!android::base::EndsWith(path, tail)) return false;
+  return library_search_paths.count(path.substr(0, path.size() - tail.size())) > 0;
 }
 
 static bool check_lib(const std::string& path,
-                      const std::vector<std::string>& library_search_paths,
+                      const std::unordered_set<std::string>& library_search_paths,
                       const std::unordered_set<std::string>& libraries,
                       std::vector<std::string>* errors) {
-  std::unique_ptr<void, int (*)(void*)> handle(dlopen(path.c_str(), RTLD_NOW), dlclose);
+  std::unique_ptr<void, decltype(&dlclose)> handle(dlopen(path.c_str(), RTLD_NOW), dlclose);
 
   // The current restrictions on public libraries:
   //  - It must exist only in the top level directory of "library_search_paths".
@@ -139,17 +138,17 @@
 }
 
 static bool check_path(const std::string& library_path,
-                       const std::vector<std::string>& library_search_paths,
+                       const std::unordered_set<std::string>& library_search_paths,
                        const std::unordered_set<std::string>& libraries,
                        std::vector<std::string>* errors) {
   bool success = true;
-  std::list<std::string> dirs = { library_path };
+  std::queue<std::string> dirs;
+  dirs.push(library_path);
   while (!dirs.empty()) {
     std::string dir = dirs.front();
-    dirs.pop_front();
+    dirs.pop();
 
-    auto dir_deleter = [](DIR* handle) { closedir(handle); };
-    std::unique_ptr<DIR, decltype(dir_deleter)> dirp(opendir(dir.c_str()), dir_deleter);
+    std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir(dir.c_str()), closedir);
     if (dirp == nullptr) {
       errors->push_back("Failed to open " + dir + ": " + strerror(errno));
       success = false;
@@ -164,8 +163,8 @@
       }
 
       std::string path = dir + "/" + dp->d_name;
-      if (is_directory(path)) {
-        dirs.push_back(path);
+      if (is_directory(path.c_str())) {
+        dirs.push(path);
       } else if (!check_lib(path, library_search_paths, libraries, errors)) {
         success = false;
       }
@@ -231,7 +230,8 @@
         JNIEnv* env,
         jclass clazz __attribute__((unused)),
         jobjectArray java_system_public_libraries,
-        jobjectArray java_vendor_public_libraries) {
+        jobjectArray java_vendor_public_libraries,
+        jobjectArray java_product_public_libraries) {
   bool success = true;
   std::vector<std::string> errors;
   std::string error_msg;
@@ -249,6 +249,13 @@
     errors.push_back("Errors in system public library file:" + error_msg);
   }
 
+  std::unordered_set<std::string> product_public_libraries;
+  if (!jobject_array_to_set(env, java_product_public_libraries, &product_public_libraries,
+                            &error_msg)) {
+    success = false;
+    errors.push_back("Errors in product public library file:" + error_msg);
+  }
+
   // Check the system libraries.
 
   // Check current search path and add the rest of search path configured for
@@ -256,22 +263,22 @@
   char default_search_paths[PATH_MAX];
   android_get_LD_LIBRARY_PATH(default_search_paths, sizeof(default_search_paths));
 
-
   std::vector<std::string> library_search_paths = android::base::Split(default_search_paths, ":");
+
   // Remove everything pointing outside of /system/lib*
-  library_search_paths.erase(
-      std::remove_if(library_search_paths.begin(),
-                     library_search_paths.end(),
-                     [](const std::string& path) {
-                       return !android::base::StartsWith(path, "/system/lib");
-                     }),
-      library_search_paths.end());
+  std::unordered_set<std::string> system_library_search_paths;
+
+  for (const auto& path : library_search_paths) {
+    if (android::base::StartsWith(path, "/system/lib")) {
+      system_library_search_paths.insert(path);
+    }
+  }
 
   // This path should be tested too - this is because apps may rely on some
   // libraries being available in /system/${LIB}/
-  library_search_paths.push_back(kSystemLibraryPath);
+  system_library_search_paths.insert(kSystemLibraryPath);
 
-  if (!check_path(kSystemLibraryPath, library_search_paths, system_public_libraries, &errors)) {
+  if (!check_path(kSystemLibraryPath, system_library_search_paths, system_public_libraries, &errors)) {
     success = false;
   }
 
@@ -291,6 +298,13 @@
     }
   }
 
+  // Check the product libraries, if /product/lib exists.
+  if (is_directory(kProductLibraryPath.c_str())) {
+    if (!check_path(kProductLibraryPath, { kProductLibraryPath }, product_public_libraries, &errors)) {
+      success = false;
+    }
+  }
+
   // Check the vendor libraries.
   if (!check_path(kVendorLibraryPath, { kVendorLibraryPath }, vendor_public_libraries, &errors)) {
     success = false;
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
index 72acf64..a30db52 100644
--- a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -37,8 +37,12 @@
 
 class LinkerNamespacesHelper {
     private final static String PUBLIC_CONFIG_DIR = "/system/etc/";
+    private final static String PRODUCT_CONFIG_DIR = "/product/etc/";
     private final static String SYSTEM_CONFIG_FILE = PUBLIC_CONFIG_DIR + "public.libraries.txt";
-    private final static String OEM_CONFIG_FILE_PATTERN = "public\\.libraries-([A-Za-z0-9-_]+)\\.txt";
+    private final static Pattern EXTENSION_CONFIG_FILE_PATTERN = Pattern.compile(
+            "public\\.libraries-([A-Za-z0-9\\-_]+)\\.txt");
+    private final static Pattern EXTENSION_LIBRARY_FILE_PATTERN = Pattern.compile(
+            "lib[^.]+\\.([A-Za-z0-9\\-_]+)\\.so");
     private final static String VENDOR_CONFIG_FILE = "/vendor/etc/public.libraries.txt";
     private final static String[] PUBLIC_SYSTEM_LIBRARIES = {
         "libaaudio.so",
@@ -104,6 +108,37 @@
         return libs;
     }
 
+    private static String readExtensionConfigFiles(String configDir, List<String> libs) throws IOException {
+        File[] configFiles = new File(configDir).listFiles(
+                new FilenameFilter() {
+                    public boolean accept(File dir, String name) {
+                        return EXTENSION_CONFIG_FILE_PATTERN.matcher(name).matches();
+                    }
+                });
+        if (configFiles == null) return null;
+
+        for (File configFile: configFiles) {
+            String fileName = configFile.toPath().getFileName().toString();
+            Matcher configMatcher = EXTENSION_CONFIG_FILE_PATTERN.matcher(fileName);
+            if (configMatcher.matches()) {
+                String companyName = configMatcher.group(1);
+                // a lib in public.libraries-acme.txt should be
+                // libFoo.acme.so
+                List<String> libNames = readPublicLibrariesFile(configFile);
+                for (String lib : libNames) {
+                    Matcher libMatcher = EXTENSION_LIBRARY_FILE_PATTERN.matcher(lib);
+                    if (libMatcher.matches() && libMatcher.group(1).equals(companyName)) {
+                        libs.add(lib);
+                    } else {
+                        return "Library \"" + lib + "\" in " + configFile.toString()
+                                + " must have company name " + companyName + " as suffix.";
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     public static String runAccessibilityTest() throws IOException {
         List<String> systemLibs = new ArrayList<>();
 
@@ -116,44 +151,18 @@
 
         // Check if public.libraries.txt contains libs other than the
         // public system libs (NDK libs).
-        for (String lib : readPublicLibrariesFile(new File(SYSTEM_CONFIG_FILE))) {
-            if (!systemLibs.contains(lib)) {
-                return "Library \"" + lib + "\" in " + SYSTEM_CONFIG_FILE
-                        + " is not an allowed system lib.";
-            }
-        }
-
-        Pattern oemConfigFilePattern = Pattern.compile(OEM_CONFIG_FILE_PATTERN);
-        File[] oemConfigFiles = new File(PUBLIC_CONFIG_DIR).listFiles(
-                new FilenameFilter() {
-                    public boolean accept(File dir, String name) {
-                        return oemConfigFilePattern.matcher(name).matches();
-                    }
-                });
 
         List<String> oemLibs = new ArrayList<>();
-        for (File configFile : oemConfigFiles) {
-            String fileName = configFile.toPath().getFileName().toString();
-            Matcher matcher = oemConfigFilePattern.matcher(fileName);
-            if (matcher.matches()) {
-                String oemName = matcher.group(1);
-                // a lib in /system/etc/public.libraries-acme.txt should be
-                // libFoo.acme.so
-                Pattern libNamePattern = Pattern.compile("lib.+\\." + oemName + "\\.so");
-                List<String> libs = readPublicLibrariesFile(configFile);
-                for (String lib : libs) {
-                    if (libNamePattern.matcher(lib).matches()) {
-                        oemLibs.add(lib);
-                    } else {
-                        return "OEM library \"" + lib + "\" in " + configFile.toString()
-                                + " must have company name " + oemName + " as suffix.";
-                    }
-                }
-            }
-        }
+        String oemLibsError = readExtensionConfigFiles(PUBLIC_CONFIG_DIR, oemLibs);
+        if (oemLibsError != null) return oemLibsError;
         // OEM libs that passed above tests are available to Android app via JNI
         systemLibs.addAll(oemLibs);
 
+        // PRODUCT libs that passed are also available
+        List<String> productLibs = new ArrayList<>();
+        String productLibsError = readExtensionConfigFiles(PRODUCT_CONFIG_DIR, productLibs);
+        if (productLibsError != null) return productLibsError;
+
         List<String> vendorLibs = readPublicLibrariesFile(new File(VENDOR_CONFIG_FILE));
 
         // Make sure that the libs in grey-list are not exposed to apps. In fact, it
@@ -172,11 +181,13 @@
         }
 
         return runAccessibilityTestImpl(systemLibs.toArray(new String[systemLibs.size()]),
-                                        vendorLibs.toArray(new String[vendorLibs.size()]));
+                                        vendorLibs.toArray(new String[vendorLibs.size()]),
+                                        productLibs.toArray(new String[productLibs.size()]));
     }
 
     private static native String runAccessibilityTestImpl(String[] publicSystemLibs,
-                                                          String[] publicVendorLibs);
+                                                          String[] publicVendorLibs,
+                                                          String[] publicProductLibs);
 
     private static void invokeIncrementGlobal(Class<?> clazz) throws Exception {
         clazz.getMethod("incrementGlobal").invoke(null);
diff --git a/tests/tests/jvmti/attaching/AndroidTest.xml b/tests/tests/jvmti/attaching/AndroidTest.xml
index 5723956..0e927a3 100644
--- a/tests/tests/jvmti/attaching/AndroidTest.xml
+++ b/tests/tests/jvmti/attaching/AndroidTest.xml
@@ -27,4 +27,8 @@
         <option name="package" value="android.jmvti.attaching.cts" />
         <option name="runtime-hint" value="18s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/tests/location/Android.mk b/tests/tests/location/Android.mk
index 4e4257e..8297a75 100644
--- a/tests/tests/location/Android.mk
+++ b/tests/tests/location/Android.mk
@@ -29,7 +29,7 @@
 LOCAL_JAVA_LIBRARIES := telephony-common android.test.base.stubs
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    compatibility-device-util ctstestrunner apache-commons-math
+    compatibility-device-util ctstestrunner apache-commons-math platform-test-annotations
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src/android/location/cts) \
    $(call all-proto-files-under, protos)
@@ -48,7 +48,7 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_JAVA_LIBRARIES := telephony-common android.test.base.stubs
 
diff --git a/tests/tests/location/AndroidManifest.xml b/tests/tests/location/AndroidManifest.xml
index 6e3bbf1..1b85f8f 100644
--- a/tests/tests/location/AndroidManifest.xml
+++ b/tests/tests/location/AndroidManifest.xml
@@ -16,7 +16,8 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.location.cts">
+    package="android.location.cts"
+    android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
diff --git a/tests/tests/location/src/android/location/cts/EmergencyCallWifiTest.java b/tests/tests/location/src/android/location/cts/EmergencyCallWifiTest.java
index 7ebb04a..1c6ac6c 100644
--- a/tests/tests/location/src/android/location/cts/EmergencyCallWifiTest.java
+++ b/tests/tests/location/src/android/location/cts/EmergencyCallWifiTest.java
@@ -21,10 +21,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.wifi.ScanResult;
-import android.net.wifi.WifiInfo;
-import android.telephony.TelephonyManager;
 import android.net.wifi.WifiManager;
-import android.test.AndroidTestCase;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
 import java.io.IOException;
@@ -63,6 +61,7 @@
         mWifiScanReceiver = new WifiScanReceiver();
     }
 
+    @AppModeFull(reason = "Requires registering a broadcast receiver")
     public void testWifiScan() throws Exception {
         mContext.registerReceiver(mWifiScanReceiver, new IntentFilter(
                 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
index 7a6c152..5edca64 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
@@ -19,6 +19,7 @@
 import android.location.GnssMeasurement;
 import android.location.GnssMeasurementsEvent;
 import android.location.GpsStatus;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
 import java.util.Arrays;
@@ -90,6 +91,7 @@
     /**
      * Test for GPS measurements before a location fix.
      */
+    @AppModeFull(reason = "Requires use of extra LocationManager commands")
     public void testGnssMeasurementWhenNoLocation() throws Exception {
         // Checks if GPS hardware feature is present, skips test (pass) if not,
         // and hard asserts that Location/GPS (Provider) is turned on if is Cts Verifier.
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 3af213e..d58ebb6 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -38,6 +38,7 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.test.UiThreadTest;
 
@@ -1046,6 +1047,7 @@
         mManager.unregisterGnssStatusCallback(callback);
     }
 
+    @AppModeFull(reason = "Requires use of extra LocationManager commands")
     public void testSendExtraCommand() {
         // this test assumes TEST_MOCK_PROVIDER_NAME was created in setUp.
         assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME));
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index 2e84264..96c41aa 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -31,6 +31,7 @@
 import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
 import android.util.Log;
@@ -260,6 +261,7 @@
         }
     }
 
+    @AppModeFull
     public void testSendExtraCommand() {
         addTestProvider(LocationManager.NETWORK_PROVIDER, Criteria.ACCURACY_COARSE, true, false, true);
         addTestProvider(LocationManager.GPS_PROVIDER, Criteria.ACCURACY_FINE, false, true, false);
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 6758a4d..dbec359 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -71,6 +71,7 @@
 # do not compress VP9 video files
 LOCAL_AAPT_FLAGS := -0 .vp9
 LOCAL_AAPT_FLAGS += -0 .ts
+LOCAL_AAPT_FLAGS += -0 .heic
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/media/res/raw/video_1280x720_hevc_hdr10_static_3mbps.mp4 b/tests/tests/media/res/raw/video_1280x720_hevc_hdr10_static_3mbps.mp4
new file mode 100644
index 0000000..17150d4
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_hevc_hdr10_static_3mbps.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_vp9_hdr_static_3mbps.mkv b/tests/tests/media/res/raw/video_1280x720_vp9_hdr_static_3mbps.mkv
new file mode 100644
index 0000000..40677fd
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_vp9_hdr_static_3mbps.mkv
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 954c331..fcf4d38 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -270,6 +270,9 @@
     }
 
     public void testCheckingZenModeBlockDoesNotRequireNotificationPolicyAccess() throws Exception {
+        if (!mSupportNotificationPolicyAccess) {
+            return;
+        }
         try {
             // set zen mode to priority only, so playSoundEffect will check notification policy
             Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(),
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index aae53fc..4202e32 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -27,6 +27,7 @@
 import android.media.Image;
 import android.media.AudioManager;
 import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
 import android.media.MediaCodecList;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
@@ -50,7 +51,10 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.zip.CRC32;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import static android.media.MediaCodecInfo.CodecProfileLevel.*;
 
@@ -694,6 +698,179 @@
         }
     }
 
+    public void testVp9HdrStaticMetadata() throws Exception {
+        final String staticInfo =
+                "00 d0 84 80 3e c2 33 c4  86 4c 1d b8 0b 13 3d 42" +
+                "40 e8 03 64 00 e8 03 2c  01                     " ;
+        testHdrStaticMetadata(R.raw.video_1280x720_vp9_hdr_static_3mbps,
+                staticInfo, true /*metadataInContainer*/);
+    }
+
+    public void testH265HDR10StaticMetadata() throws Exception {
+        final String staticInfo =
+                "00 c2 33 c4 86 4c 1d b8  0b d0 84 80 3e 13 3d 42" +
+                "40 e8 03 00 00 e8 03 90  01                     " ;
+        testHdrStaticMetadata(R.raw.video_1280x720_hevc_hdr10_static_3mbps,
+                staticInfo, false /*metadataInContainer*/);
+    }
+
+    private void testHdrStaticMetadata(int res, String pattern, boolean metadataInContainer)
+            throws Exception {
+        AssetFileDescriptor infd = null;
+        MediaExtractor extractor = null;
+
+        try {
+            infd = mResources.openRawResourceFd(res);
+            extractor = new MediaExtractor();
+            extractor.setDataSource(infd.getFileDescriptor(),
+                    infd.getStartOffset(), infd.getLength());
+
+            MediaFormat format = null;
+            int trackIndex = -1;
+            for (int i = 0; i < extractor.getTrackCount(); i++) {
+                format = extractor.getTrackFormat(i);
+                if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
+                    trackIndex = i;
+                    break;
+                }
+            }
+
+            assertTrue("Extractor failed to extract video track",
+                    format != null && trackIndex >= 0);
+            if (metadataInContainer) {
+                verifyHdrStaticInfo("Extractor failed to extract static info", format, pattern);
+            }
+
+            extractor.selectTrack(trackIndex);
+            Log.v(TAG, "format " + format);
+
+            String mime = format.getString(MediaFormat.KEY_MIME);
+            // setting profile and level
+            if (MediaFormat.MIMETYPE_VIDEO_HEVC.equals(mime)) {
+                assertEquals("Extractor set wrong profile",
+                        MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10,
+                        format.getInteger(MediaFormat.KEY_PROFILE));
+            } else if (MediaFormat.MIMETYPE_VIDEO_VP9.equals(mime)) {
+                // The muxer might not have put VP9 CSD in the mkv, we manually patch
+                // it here so that we only test HDR when decoder supports it.
+                format.setInteger(MediaFormat.KEY_PROFILE,
+                        MediaCodecInfo.CodecProfileLevel.VP9Profile2HDR);
+            } else {
+                fail("Codec " + mime + " shouldn't be tested with this test!");
+            }
+            String[] decoderNames = MediaUtils.getDecoderNames(format);
+
+            if (decoderNames == null || decoderNames.length == 0) {
+                MediaUtils.skipTest("No video codecs supports HDR");
+                return;
+            }
+
+            final Surface surface = getActivity().getSurfaceHolder().getSurface();
+            final MediaExtractor finalExtractor = extractor;
+
+            for (String name : decoderNames) {
+                Log.d(TAG, "Testing candicate decoder " + name);
+                CountDownLatch latch = new CountDownLatch(1);
+                extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
+
+                MediaCodec decoder = MediaCodec.createByCodecName(name);
+                decoder.setCallback(new MediaCodec.Callback() {
+                    boolean mInputEOS;
+                    boolean mOutputReceived;
+
+                    @Override
+                    public void onOutputBufferAvailable(
+                            MediaCodec codec, int index, BufferInfo info) {
+                        if (mOutputReceived) {
+                            return;
+                        }
+
+                        MediaFormat bufferFormat = codec.getOutputFormat(index);
+                        Log.i(TAG, "got output buffer: format " + bufferFormat);
+
+                        codec.releaseOutputBuffer(index,  false);
+                        verifyHdrStaticInfo("Output buffer has wrong static info",
+                                bufferFormat, pattern);
+                        mOutputReceived = true;
+                        latch.countDown();
+                    }
+
+                    @Override
+                    public void onInputBufferAvailable(MediaCodec codec, int index) {
+                        // keep queuing until intput EOS, or first output buffer received.
+                        if (mInputEOS || mOutputReceived) {
+                            return;
+                        }
+
+                        ByteBuffer inputBuffer = codec.getInputBuffer(index);
+
+                        if (finalExtractor.getSampleTrackIndex() == -1) {
+                            codec.queueInputBuffer(
+                                    index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+                            mInputEOS = true;
+                        } else {
+                            int size = finalExtractor.readSampleData(inputBuffer, 0);
+                            long timestamp = finalExtractor.getSampleTime();
+                            finalExtractor.advance();
+                            codec.queueInputBuffer(index, 0, size, timestamp, 0);
+                        }
+                    }
+
+                    @Override
+                    public void onError(MediaCodec codec, MediaCodec.CodecException e) {
+                        Log.i(TAG, "got codec exception", e);
+                        fail("received codec error during decode" + e);
+                    }
+
+                    @Override
+                    public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
+                        Log.i(TAG, "got output format: " + format);
+                        verifyHdrStaticInfo("Output format has wrong static info",
+                                format, pattern);
+                    }
+                });
+                decoder.configure(format, surface, null/*crypto*/, 0/*flags*/);
+                decoder.start();
+                try {
+                    assertTrue(latch.await(2000, TimeUnit.MILLISECONDS));
+                } catch (InterruptedException e) {
+                    fail("playback interrupted");
+                }
+                decoder.stop();
+                decoder.release();
+            }
+        } finally {
+            if (extractor != null) {
+                extractor.release();
+            }
+            if (infd != null) {
+                infd.close();
+            }
+        }
+    }
+
+    private void verifyHdrStaticInfo(String reason, MediaFormat format, String pattern) {
+        ByteBuffer staticMetadataBuffer = format.containsKey("hdr-static-info") ?
+                format.getByteBuffer("hdr-static-info") : null;
+        assertTrue(reason + ": empty",
+                staticMetadataBuffer != null && staticMetadataBuffer.remaining() > 0);
+        assertTrue(reason + ": mismatch",
+                Arrays.equals(loadByteArrayFromString(pattern), staticMetadataBuffer.array()));
+    }
+
+    // helper to load byte[] from a String
+    private byte[] loadByteArrayFromString(final String str) {
+        Pattern pattern = Pattern.compile("[0-9a-fA-F]{2}");
+        Matcher matcher = pattern.matcher(str);
+        // allocate a large enough byte array first
+        byte[] tempArray = new byte[str.length() / 2];
+        int i = 0;
+        while (matcher.find()) {
+          tempArray[i++] = (byte)Integer.parseInt(matcher.group(), 16);
+        }
+        return Arrays.copyOfRange(tempArray, 0, i);
+    }
+
     public void testDecodeFragmented() throws Exception {
         testDecodeFragmented(R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz,
                 R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz_fragmented);
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
index 86615f5..e4911ed1 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
@@ -39,6 +39,7 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -63,7 +64,7 @@
         // full boost, full cut, target ref level: -23dBFS, heavy compression: no
         DrcParams drcParams = new DrcParams(127, 127, 92, 0);
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot5_drclevel_mp4,
-                -1, null, drcParams);
+                -1, null, drcParams, null /*decoderName: use default decoder*/);
         DecoderTest decTester = new DecoderTest();
         decTester.checkEnergy(decSamples, decParams, 2, 0.70f);
     }
@@ -76,7 +77,7 @@
     public void testDecodeAacDrcFullM4a() throws Exception {
         AudioParameter decParams = new AudioParameter();
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot5_drcfull_mp4,
-                -1, null, null);
+                -1, null, null, null /*decoderName: use default decoder*/);
         DecoderTest decTester = new DecoderTest();
         decTester.checkEnergy(decSamples, decParams, 2, 0.80f);
     }
@@ -91,7 +92,7 @@
         // half boost, half cut, target ref level: -20dBFS, heavy compression: no
         DrcParams drcParams = new DrcParams(63, 63, 80, 0);
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot2_drchalf_mp4,
-                -1, null, drcParams);
+                -1, null, drcParams, null /*decoderName: use default decoder*/);
         DecoderTest decTester = new DecoderTest();
         decTester.checkEnergy(decSamples, decParams, 2, 0.80f);
     }
@@ -106,7 +107,7 @@
         // no boost, no cut, target ref level: -16dBFS, heavy compression: no
         DrcParams drcParams = new DrcParams(0, 0, 64, 0);       // normalize to -16dBFS
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot5_drcoff_mp4,
-                -1, null, drcParams);
+                -1, null, drcParams, null /*decoderName: use default decoder*/);
         DecoderTest decTester = new DecoderTest();
         decTester.checkEnergy(decSamples, decParams, 2, 0.80f);
     }
@@ -121,7 +122,7 @@
         // full boost, full cut, target ref level: -16dBFS, heavy compression: yes
         DrcParams drcParams = new DrcParams(127, 127, 64, 1);
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot2_drcheavy_mp4,
-                -1, null, drcParams);
+                -1, null, drcParams, null /*decoderName: use default decoder*/);
         DecoderTest decTester = new DecoderTest();
         decTester.checkEnergy(decSamples, decParams, 2, 0.80f);
     }
@@ -134,7 +135,7 @@
     public void testDecodeAacDrcClipM4a() throws Exception {
         AudioParameter decParams = new AudioParameter();
         short[] decSamples = decodeToMemory(decParams, R.raw.sine_2ch_48khz_aot5_drcclip_mp4,
-                -1, null, null);
+                -1, null, null, null /*decoderName: use default decoder*/);
         checkClipping(decSamples, decParams, 248.0f /* Hz */);
     }
 
@@ -152,35 +153,42 @@
     public void testDecodeUsacLoudnessM4a() throws Exception {
         Log.v(TAG, "START testDecodeUsacLoudnessM4a");
 
-        // test default loudness
-        // decoderTargetLevel = 64 --> target output level = -16.0 dBFs
-        try {
-            checkUsacLoudness(DEFAULT_DECODER_TARGET_LEVEL, 1, 1.0f);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacLoudnessM4a for default loudness failed");
-            throw new RuntimeException(e);
-        }
+        ArrayList<String> aacDecoderNames = DecoderTestXheAac.initAacDecoderNames();
+        assertTrue("No AAC decoder found", aacDecoderNames.size() > 0);
 
-        // test loudness boost
-        // decoderTargetLevel = 40 --> target output level = -10.0 dBFs
-        // normFactor = 1/(10^(-6/10)) = 3.98f
-        //    where "-6" is the difference between the default level (-16), and -10 for this test
-        try {
-            checkUsacLoudness(40, 1, (float)(1.0f/Math.pow(10.0f, -6.0f/10.0f)));
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness boost failed");
-            throw new RuntimeException(e);
-        }
+        for (String aacDecName : aacDecoderNames) {
+            // test default loudness
+            // decoderTargetLevel = 64 --> target output level = -16.0 dBFs
+            try {
+                checkUsacLoudness(DEFAULT_DECODER_TARGET_LEVEL, 1, 1.0f, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacLoudnessM4a for default loudness failed for " +
+                        aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test loudness attenuation
-        // decoderTargetLevel = 96 --> target output level = -24.0 dBFs
-        // normFactor = 1/(10^(8/10)) = 0.15f
-        //     where -8 is the difference between the default level (-16), and -24 for this test
-        try {
-            checkUsacLoudness(96, 0, (float)(1.0f/Math.pow(10.0f, 8.0f/10.0f)));
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness attenuation failed");
-            throw new RuntimeException(e);
+            // test loudness boost
+            // decoderTargetLevel = 40 --> target output level = -10.0 dBFs
+            // normFactor = 1/(10^(-6/10)) = 3.98f
+            //   where "-6" is the difference between the default level (-16), and -10 for this test
+            try {
+                checkUsacLoudness(40, 1, (float)(1.0f/Math.pow(10.0f, -6.0f/10.0f)), aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness boost failed for " + aacDecName);
+                throw new RuntimeException(e);
+            }
+
+            // test loudness attenuation
+            // decoderTargetLevel = 96 --> target output level = -24.0 dBFs
+            // normFactor = 1/(10^(8/10)) = 0.15f
+            //     where 8 is the difference between the default level (-16), and -24 for this test
+            try {
+                checkUsacLoudness(96, 0, (float)(1.0f/Math.pow(10.0f, 8.0f/10.0f)), aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacLoudnessM4a for loudness attenuation failed for "
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -307,16 +315,16 @@
     /**
      * USAC test DRC loudness
      */
-    private void checkUsacLoudness(int decoderTargetLevel, int heavy, float normFactor)
-            throws Exception {
+    private void checkUsacLoudness(int decoderTargetLevel, int heavy, float normFactor,
+            String decoderName) throws Exception {
         AudioParameter decParams = new AudioParameter();
         DrcParams drcParams_def  = new DrcParams(127, 127, DEFAULT_DECODER_TARGET_LEVEL, 1);
         DrcParams drcParams_test = new DrcParams(127, 127, decoderTargetLevel, heavy);
 
         short[] decSamples_def = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot42_19_lufs_mp4,
-                -1, null, drcParams_def);
+                -1, null, drcParams_def, decoderName);
         short[] decSamples_test = decodeToMemory(decParams, R.raw.noise_2ch_48khz_aot42_19_lufs_mp4,
-                -1, null, drcParams_test);
+                -1, null, drcParams_test, decoderName);
 
         DecoderTestXheAac decTesterXheAac = new DecoderTestXheAac();
         float[] nrg_def  = decTesterXheAac.checkEnergyUSAC(decSamples_def, decParams, 2, 1);
@@ -388,7 +396,7 @@
     //          - no need/use of resetMode, configMode
     //       Split method so code can be shared
     private short[] decodeToMemory(AudioParameter audioParams, int testinput,
-            int eossample, List<Long> timestamps, DrcParams drcParams)
+            int eossample, List<Long> timestamps, DrcParams drcParams, String decoderName)
             throws IOException
     {
         String localTag = TAG + "#decodeToMemory";
@@ -413,7 +421,11 @@
         assertTrue("not an audio file", mime.startsWith("audio/"));
 
         MediaFormat configFormat = format;
-        codec = MediaCodec.createDecoderByType(mime);
+        if (decoderName == null) {
+            codec = MediaCodec.createDecoderByType(mime);
+        } else {
+            codec = MediaCodec.createByCodecName(decoderName);
+        }
 
         // set DRC parameters
         if (drcParams != null) {
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
index cc294a9..2c549f2 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
@@ -25,6 +25,7 @@
 import android.media.cts.DecoderTestAacDrc.DrcParams;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -40,6 +41,7 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -48,11 +50,39 @@
 
     private Resources mResources;
 
+    // list of all AAC decoders as enumerated through the MediaCodecList
+    // lazy initialization in setUp()
+    private static ArrayList<String> sAacDecoderNames;
+
     @Before
     public void setUp() throws Exception {
         final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
         assertNotNull(inst);
         mResources = inst.getContext().getResources();
+        // build a list of all AAC decoders on which to run the test
+        if (sAacDecoderNames == null) {
+            sAacDecoderNames = initAacDecoderNames();
+        }
+    }
+
+    protected static ArrayList<String> initAacDecoderNames() {
+        // at least 1 AAC decoder expected
+        ArrayList<String> aacDecoderNames = new ArrayList<String>(1);
+        final MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        final MediaCodecInfo[] mediaCodecInfos = mediaCodecList.getCodecInfos();
+        for (MediaCodecInfo mediaCodecInfo : mediaCodecInfos) {
+            if (mediaCodecInfo.isEncoder()) {
+                continue;
+            }
+            final String[] mimeTypes = mediaCodecInfo.getSupportedTypes();
+            for (String mimeType : mimeTypes) {
+                if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
+                    aacDecoderNames.add(mediaCodecInfo.getName());
+                    break;
+                }
+            }
+        }
+        return aacDecoderNames;
     }
 
     /**
@@ -62,112 +92,119 @@
     public void testDecodeUsacDrcEffectTypeM4a() throws Exception {
         Log.v(TAG, "START testDecodeUsacDrcEffectTypeM4a");
 
-        // test DRC effectTypeID 1 "NIGHT"
-        // L -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
-        // R +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
-        try {
-            checkUsacDrcEffectType(1, 0.5011f, 1.9952f, "Night", 2, 0);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Night failed");
-            throw new RuntimeException(e);
-        }
+        assertTrue("No AAC decoder found", sAacDecoderNames.size() > 0);
 
-        // test DRC effectTypeID 2 "NOISY"
-        // L +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
-        // R -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
-        try {
-            checkUsacDrcEffectType(2, 1.9952f, 0.2511f, "Noisy", 2, 0);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Noisy failed");
-            throw new RuntimeException(e);
-        }
+        for (String aacDecName : sAacDecoderNames) {
+            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a running for dec=" + aacDecName);
+            // test DRC effectTypeID 1 "NIGHT"
+            // L -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
+            // R +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
+            try {
+                checkUsacDrcEffectType(1, 0.5011f, 1.9952f, "Night", 2, 0, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Night/2/0 failed for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 3 "LIMITED"
-        // L -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
-        // R +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
-        try {
-            checkUsacDrcEffectType(3, 0.2511f, 3.9810f, "Limited", 2, 0);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type Limited failed");
-            throw new RuntimeException(e);
-        }
+            // test DRC effectTypeID 2 "NOISY"
+            // L +3dB -> normalization factor = 1/(10^( 3/10)) = 1.9952f
+            // R -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+            try {
+                checkUsacDrcEffectType(2, 1.9952f, 0.2511f, "Noisy", 2, 0, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Noisy/2/0 failed for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 6 "GENERAL"
-        // L +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
-        // R -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
-        try {
-            checkUsacDrcEffectType(6, 3.9810f, 0.5011f, "General", 2, 0);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a effect type General failed");
-            throw new RuntimeException(e);
-        }
+            // test DRC effectTypeID 3 "LIMITED"
+            // L -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+            // R +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+            try {
+                checkUsacDrcEffectType(3, 0.2511f, 3.9810f, "Limited", 2, 0, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Limited/2/0 failed for dec="
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 1 "NIGHT"
-        // L    -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
-        // R    +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
-        // mono -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
-        try {
-            checkUsacDrcEffectType(1, 0.2511f, 3.9810f, "Night", 2, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
-        try {
-            checkUsacDrcEffectType(1, 0.2511f, 0.0f, "Night", 1, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+            // test DRC effectTypeID 6 "GENERAL"
+            // L +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+            // R -3dB -> normalization factor = 1/(10^(-3/10)) = 0.5011f
+            try {
+                checkUsacDrcEffectType(6, 3.9810f, 0.5011f, "General", 2, 0, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a General/2/0 failed for dec="
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 2 "NOISY"
-        // L    +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
-        // R    -9dB -> normalization factor = 1/(10^(-9/10))  = 0.1258f
-        // mono +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
-        try {
-            checkUsacDrcEffectType(2, 3.9810f, 0.1258f, "Noisy", 2, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
-        try {
-            checkUsacDrcEffectType(2, 3.9810f, 0.0f, "Noisy", 1, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+            // test DRC effectTypeID 1 "NIGHT"
+            // L    -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+            // R    +6dB -> normalization factor = 1/(10^( 6/10)) = 3.9810f
+            // mono -6dB -> normalization factor = 1/(10^(-6/10)) = 0.2511f
+            try {
+                checkUsacDrcEffectType(1, 0.2511f, 3.9810f, "Night", 2, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Night/2/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
+            try {
+                checkUsacDrcEffectType(1, 0.2511f, 0.0f, "Night", 1, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Night/1/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 3 "LIMITED"
-        // L    -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
-        // R    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
-        // mono -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
-        try {
-            checkUsacDrcEffectType(3, 0.1258f, 7.9432f, "Limited", 2, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
-        try {
-            checkUsacDrcEffectType(3, 0.1258f, 0.0f, "Limited", 1, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+            // test DRC effectTypeID 2 "NOISY"
+            // L    +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
+            // R    -9dB -> normalization factor = 1/(10^(-9/10))  = 0.1258f
+            // mono +6dB -> normalization factor = 1/(10^( 6/10))   = 3.9810f
+            try {
+                checkUsacDrcEffectType(2, 3.9810f, 0.1258f, "Noisy", 2, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Noisy/2/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
+            try {
+                checkUsacDrcEffectType(2, 3.9810f, 0.0f, "Noisy", 1, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Night/2/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // test DRC effectTypeID 6 "GENERAL"
-        // L    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
-        // R    -6dB -> normalization factor = 1/(10^(-6/10))  = 0.2511f
-        // mono +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
-        try {
-            checkUsacDrcEffectType(6, 7.9432f, 0.2511f, "General", 2, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
-        }
-        try {
-            checkUsacDrcEffectType(6, 7.9432f, 0.0f, "General", 1, 1);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a FAILED!");
-            throw new RuntimeException(e);
+            // test DRC effectTypeID 3 "LIMITED"
+            // L    -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
+            // R    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+            // mono -9dB -> normalization factor = 1/(10^(-9/10)) = 0.1258f
+            try {
+                checkUsacDrcEffectType(3, 0.1258f, 7.9432f, "Limited", 2, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Limited/2/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
+            try {
+                checkUsacDrcEffectType(3, 0.1258f, 0.0f, "Limited", 1, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a Limited/1/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
+
+            // test DRC effectTypeID 6 "GENERAL"
+            // L    +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+            // R    -6dB -> normalization factor = 1/(10^(-6/10))  = 0.2511f
+            // mono +9dB -> normalization factor = 1/(10^( 9/10)) = 7.9432f
+            try {
+                checkUsacDrcEffectType(6, 7.9432f, 0.2511f, "General", 2, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a General/2/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
+            try {
+                checkUsacDrcEffectType(6, 7.9432f, 0.0f, "General", 1, 1, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacDrcEffectTypeM4a General/1/1 for dec=" + aacDecName);
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -178,44 +215,52 @@
     public void testDecodeUsacStreamSwitchingM4a() throws Exception {
         Log.v(TAG, "START testDecodeUsacStreamSwitchingM4a");
 
-        // Stereo
-        // switch between SBR ratios and stereo modes
-        try {
-            checkUsacStreamSwitching(2.5459829E12f, 2,
-            R.raw.noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+        assertTrue("No AAC decoder found", sAacDecoderNames.size() > 0);
 
-        // Mono
-        // switch between SBR ratios and stereo modes
-        try {
-            checkUsacStreamSwitching(2.24669126E12f, 1,
-            R.raw.noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+        for (String aacDecName : sAacDecoderNames) {
+            // Stereo
+            // switch between SBR ratios and stereo modes
+            try {
+                checkUsacStreamSwitching(2.5459829E12f, 2,
+                        R.raw.noise_2ch_44_1khz_aot42_19_lufs_config_change_mp4, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacStreamSwitchingM4a failed 2ch sbr/stereo switch for "
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // Stereo
-        // switch between USAC modes
-        try {
-            checkUsacStreamSwitching(2.1E12f, 2,
-            R.raw.noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
-            throw new RuntimeException(e);
-        }
+            // Mono
+            // switch between SBR ratios and stereo modes
+            try {
+                checkUsacStreamSwitching(2.24669126E12f, 1,
+                        R.raw.noise_1ch_38_4khz_aot42_19_lufs_config_change_mp4, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacStreamSwitchingM4a failed 1ch sbr/stereo switch for "
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
 
-        // Mono
-        // switch between USAC modes
-        try {
-            checkUsacStreamSwitching(1.7E12f, 1,
-            R.raw.noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacStreamSwitchingM4a FAILED!");
-            throw new RuntimeException(e);
+            // Stereo
+            // switch between USAC modes
+            try {
+                checkUsacStreamSwitching(2.1E12f, 2,
+                        R.raw.noise_2ch_35_28khz_aot42_19_lufs_drc_config_change_mp4, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacStreamSwitchingM4a failed 2ch USAC mode switch for "
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
+
+            // Mono
+            // switch between USAC modes
+            try {
+                checkUsacStreamSwitching(1.7E12f, 1,
+                        R.raw.noise_1ch_29_4khz_aot42_19_lufs_drc_config_change_mp4, aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacStreamSwitchingM4a failed 1ch USAC mode switch for "
+                        + aacDecName);
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -226,16 +271,21 @@
     public void testDecodeUsacSamplingRatesM4a() throws Exception {
         Log.v(TAG, "START testDecodeUsacSamplingRatesM4a");
 
-        try {
-            checkUsacSamplingRate(R.raw.noise_2ch_08khz_aot42_19_lufs_mp4);
-            checkUsacSamplingRate(R.raw.noise_2ch_12khz_aot42_19_lufs_mp4);
-            checkUsacSamplingRate(R.raw.noise_2ch_22_05khz_aot42_19_lufs_mp4);
-            checkUsacSamplingRate(R.raw.noise_2ch_64khz_aot42_19_lufs_mp4);
-            checkUsacSamplingRate(R.raw.noise_2ch_88_2khz_aot42_19_lufs_mp4);
-            checkUsacSamplingRateWoLoudness(R.raw.noise_2ch_19_2khz_aot42_no_ludt_mp4);
-        } catch (Exception e) {
-            Log.v(TAG, "testDecodeUsacSamplingRatesM4a FAILED!");
-            throw new RuntimeException(e);
+        assertTrue("No AAC decoder found", sAacDecoderNames.size() > 0);
+
+        for (String aacDecName : sAacDecoderNames) {
+            try {
+                checkUsacSamplingRate(R.raw.noise_2ch_08khz_aot42_19_lufs_mp4, aacDecName);
+                checkUsacSamplingRate(R.raw.noise_2ch_12khz_aot42_19_lufs_mp4, aacDecName);
+                checkUsacSamplingRate(R.raw.noise_2ch_22_05khz_aot42_19_lufs_mp4, aacDecName);
+                checkUsacSamplingRate(R.raw.noise_2ch_64khz_aot42_19_lufs_mp4, aacDecName);
+                checkUsacSamplingRate(R.raw.noise_2ch_88_2khz_aot42_19_lufs_mp4, aacDecName);
+                checkUsacSamplingRateWoLoudness(R.raw.noise_2ch_19_2khz_aot42_no_ludt_mp4,
+                        aacDecName);
+            } catch (Exception e) {
+                Log.v(TAG, "testDecodeUsacSamplingRatesM4a for decoder" + aacDecName);
+                throw new RuntimeException(e);
+            }
         }
     }
 
@@ -248,7 +298,8 @@
      * USAC test DRC Effect Type
      */
     private void checkUsacDrcEffectType(int effectTypeID, float normFactor_L, float normFactor_R,
-                 String effectTypeName, int nCh, int aggressiveDrc) throws Exception {
+                 String effectTypeName, int nCh, int aggressiveDrc, String decoderName)
+                         throws Exception {
         int testinput = -1;
         AudioParameter decParams = new AudioParameter();
         DrcParams drcParams_def  = new DrcParams(127, 127, 96, 0, -1);
@@ -265,9 +316,9 @@
         }
 
         short[] decSamples_def  = decodeToMemory(decParams, testinput,
-                -1, null, drcParams_def);
+                -1, null, drcParams_def, decoderName);
         short[] decSamples_test = decodeToMemory(decParams, testinput,
-                -1, null, drcParams_test);
+                -1, null, drcParams_test, decoderName);
 
         float[] nrg_def  = checkEnergyUSAC(decSamples_def, decParams, nCh, 1, 0);
         float[] nrg_test = checkEnergyUSAC(decSamples_test, decParams, nCh, 1, 1);
@@ -290,14 +341,15 @@
     /**
      * USAC test stream switching
      */
-    private void checkUsacStreamSwitching(float nrg_ref, int encNch, int testinput) throws Exception
+    private void checkUsacStreamSwitching(float nrg_ref, int encNch, int testinput,
+            String decoderName) throws Exception
     {
         AudioParameter decParams = new AudioParameter();
         DrcParams drcParams      = new DrcParams(127, 127, 64, 0, -1);
 
         // Check stereo stream switching
         short[] decSamples = decodeToMemory(decParams, testinput,
-                -1, null, drcParams);
+                -1, null, drcParams, decoderName);
         float[] nrg = checkEnergyUSAC(decSamples, decParams, encNch, 1);
 
         float nrgRatio = nrg[0] / nrg_ref;
@@ -313,15 +365,15 @@
     /**
      * USAC test sampling rate
      */
-    private void checkUsacSamplingRate(int testinput) throws Exception {
+    private void checkUsacSamplingRate(int testinput, String decoderName) throws Exception {
         AudioParameter decParams  = new AudioParameter();
         DrcParams drcParams_def   = new DrcParams(127, 127, 64, 0, -1);
         DrcParams drcParams_test  = new DrcParams(127, 127, 96, 0, -1);
 
         short[] decSamples_def  = decodeToMemory(decParams, testinput,
-                -1, null, drcParams_def);
+                -1, null, drcParams_def, decoderName);
         short[] decSamples_test = decodeToMemory(decParams, testinput,
-                -1, null, drcParams_test);
+                -1, null, drcParams_test, decoderName);
 
         float[] nrg_def  = checkEnergyUSAC(decSamples_def, decParams, 2, 1);
         float[] nrg_test = checkEnergyUSAC(decSamples_test, decParams, 2, 1);
@@ -340,12 +392,12 @@
     /**
      * USAC test sampling rate for streams without loudness application
      */
-    private void checkUsacSamplingRateWoLoudness(int testinput) throws Exception {
+    private void checkUsacSamplingRateWoLoudness(int testinput, String decoderName) throws Exception
+    {
         AudioParameter decParams  = new AudioParameter();
         DrcParams drcParams       = new DrcParams();
 
-        short[] decSamples = decodeToMemory(decParams, testinput,
-                -1, null, drcParams);
+        short[] decSamples = decodeToMemory(decParams, testinput, -1, null, drcParams, decoderName);
 
         float[] nrg = checkEnergyUSAC(decSamples, decParams, 2, 1);
 
@@ -717,7 +769,7 @@
     }
 
     /**
-     * Decodes an compressed bitstream in the ISOBMFF into the RAM of the device.
+     * Decodes a compressed bitstream in the ISOBMFF into the RAM of the device.
      *
      * The decoder decodes compressed audio data as stored in the ISO Base Media File Format
      * (ISOBMFF) aka .mp4/.m4a. The decoder is not reproducing the waveform but stores the decoded
@@ -728,10 +780,12 @@
      * @param eossample the End-Of-Stream indicator
      * @param timestamps the time stamps to decode
      * @param drcParams the MPEG-D DRC decoder parameter configuration
+     * @param decoderName if non null, the name of the decoder to use for the decoding, otherwise
+     *     the default decoder for the format will be used
      * @throws RuntimeException
      */
     public short[] decodeToMemory(AudioParameter audioParams, int testinput,
-            int eossample, List<Long> timestamps, DrcParams drcParams)
+            int eossample, List<Long> timestamps, DrcParams drcParams, String decoderName)
             throws IOException
     {
         // TODO: code is the same as in DecoderTest, differences are:
@@ -739,7 +793,7 @@
         //          - no need/use of resetMode, configMode
         //       Split method so code can be shared
 
-        String localTag = TAG + "#decodeToMemory";
+        final String localTag = TAG + "#decodeToMemory";
         short [] decoded = new short[0];
         int decodedIdx = 0;
 
@@ -761,7 +815,11 @@
         assertTrue("not an audio file", mime.startsWith("audio/"));
 
         MediaFormat configFormat = format;
-        codec = MediaCodec.createDecoderByType(mime);
+        if (decoderName == null) {
+            codec = MediaCodec.createDecoderByType(mime);
+        } else {
+            codec = MediaCodec.createByCodecName(decoderName);
+        }
 
         // set DRC parameters
         if (drcParams != null) {
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index a5ead3f..efb3273 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -15,45 +15,37 @@
  */
 package android.media.cts;
 
-import com.android.compatibility.common.util.ApiLevelUtil;
-
-import android.content.Context;
 import android.content.pm.PackageManager;
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
+import android.media.CamcorderProfile;
 import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.media.MediaCodecList;
 import android.media.MediaDrm;
 import android.media.MediaDrmException;
 import android.media.MediaFormat;
-import android.media.CamcorderProfile;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.Looper;
-import androidx.annotation.NonNull;
-import android.test.ActivityInstrumentationTestCase2;
 import android.util.Base64;
 import android.util.Log;
 import android.view.SurfaceHolder;
 
-import java.io.IOException;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.Vector;
+import com.android.compatibility.common.util.ApiLevelUtil;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+import androidx.annotation.NonNull;
+
 /**
  * Tests of MediaPlayer streaming capabilities.
  */
@@ -129,10 +121,13 @@
         super.tearDown();
     }
 
+    private boolean isWatchDevice() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
+
     private boolean deviceHasMediaDrm() {
         // ClearKey is introduced after KitKat.
         if (ApiLevelUtil.isAtMost(android.os.Build.VERSION_CODES.KITKAT)) {
-            Log.i(TAG, "This test is designed to work after Android KitKat.");
             return false;
         }
         return true;
@@ -361,6 +356,11 @@
             Uri audioUrl, boolean audioEncrypted,
             Uri videoUrl, boolean videoEncrypted,
             int videoWidth, int videoHeight, boolean scrambled) throws Exception {
+
+        if (isWatchDevice()) {
+            return;
+        }
+
         MediaDrm drm = null;
         mSessionId = null;
         if (!scrambled) {
@@ -451,12 +451,15 @@
     }
 
     public void testQueryKeyStatus() throws Exception {
-        MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC }, "cenc", COMMON_PSSH_SCHEME_UUID);
-        if (!drm.isCryptoSchemeSupported(COMMON_PSSH_SCHEME_UUID)) {
-            stopDrm(drm);
-            throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
+        if (isWatchDevice()) {
+            // skip this test on watch because it calls
+            // addTrack that requires codec
+            return;
         }
 
+        MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC }, "cenc",
+                CLEARKEY_SCHEME_UUID);
+
         mSessionId = openSession(drm);
 
         // Test default key status, should not be defined
@@ -516,7 +519,7 @@
 
     public void testClearKeyPlaybackWebm() throws Exception {
         testClearKeyPlayback(
-            COMMON_PSSH_SCHEME_UUID,
+            CLEARKEY_SCHEME_UUID,
             MIME_VIDEO_VP8, new String[0],
             "webm", new byte[][] { CLEAR_KEY_WEBM },
             WEBM_URL, true /* audioEncrypted */,
@@ -526,7 +529,7 @@
 
     public void testClearKeyPlaybackMpeg2ts() throws Exception {
         testClearKeyPlayback(
-            COMMON_PSSH_SCHEME_UUID,
+            CLEARKEY_SCHEME_UUID,
             MIME_VIDEO_AVC, new String[0],
             "mpeg2ts", null,
             MPEG2TS_SCRAMBLED_URL, false /* audioEncrypted */,
@@ -536,7 +539,7 @@
 
     public void testPlaybackMpeg2ts() throws Exception {
         testClearKeyPlayback(
-            COMMON_PSSH_SCHEME_UUID,
+            CLEARKEY_SCHEME_UUID,
             MIME_VIDEO_AVC, new String[0],
             "mpeg2ts", null,
             MPEG2TS_CLEAR_URL, false /* audioEncrypted */,
@@ -593,8 +596,12 @@
     }
 
     public void testGetProperties() throws Exception {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC },
-                "cenc", COMMON_PSSH_SCHEME_UUID);
+                "cenc", CLEARKEY_SCHEME_UUID);
 
         try {
             // The following tests will not verify the value we are getting
@@ -628,8 +635,12 @@
     }
 
     public void testSetProperties() throws Exception {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         MediaDrm drm = startDrm(new byte[][]{CLEAR_KEY_CENC},
-                "cenc", COMMON_PSSH_SCHEME_UUID);
+                "cenc", CLEARKEY_SCHEME_UUID);
 
         try {
             // Test setting predefined string property
@@ -698,8 +709,12 @@
     private final static int CLEARKEY_MAX_SESSIONS = 10;
 
     public void testGetNumberOfSessions() {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC },
-                "cenc", COMMON_PSSH_SCHEME_UUID);
+                "cenc", CLEARKEY_SCHEME_UUID);
 
         try {
             if (getClearkeyVersion(drm).equals("1.0")) {
@@ -730,9 +745,13 @@
     }
 
     public void testHdcpLevels() {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         MediaDrm drm = null;
         try {
-            drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
+            drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
 
             if (getClearkeyVersion(drm).equals("1.0")) {
                 Log.i(TAG, "Skipping testHdcpLevels: not supported by clearkey 1.0");
@@ -747,7 +766,7 @@
                 throw new Error("expected max hdcp level to be HDCP_NO_DIGITAL_OUTPUT");
             }
         } catch(Exception e) {
-            throw new Error("Unexpected exception", e);
+            throw new Error("Unexpected exception ", e);
         } finally {
             if (drm != null) {
                 drm.close();
@@ -756,10 +775,14 @@
     }
 
     public void testSecurityLevels() {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         MediaDrm drm = null;
         byte[] sessionId = null;
         try {
-            drm = new MediaDrm(COMMON_PSSH_SCHEME_UUID);
+            drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
 
             if (getClearkeyVersion(drm).equals("1.0")) {
                 Log.i(TAG, "Skipping testSecurityLevels: not supported by clearkey 1.0");
@@ -794,7 +817,7 @@
                 }
             }
         } catch(Exception e) {
-            throw new Error("Unexpected exception", e);
+            throw new Error("Unexpected exception ", e);
         } finally  {
             if (sessionId != null) {
                 drm.closeSession(sessionId);
@@ -806,7 +829,11 @@
      }
 
     public void testSecureStop() {
-        MediaDrm drm = startDrm(new byte[][] {CLEAR_KEY_CENC}, "cenc", COMMON_PSSH_SCHEME_UUID);
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        MediaDrm drm = startDrm(new byte[][] {CLEAR_KEY_CENC}, "cenc", CLEARKEY_SCHEME_UUID);
 
         byte[] sessionId = null;
         try {
@@ -815,10 +842,6 @@
                 return;
             }
 
-            if (!drm.isCryptoSchemeSupported(COMMON_PSSH_SCHEME_UUID)) {
-                throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
-            }
-
             drm.removeAllSecureStops();
             Log.d(TAG, "Test getSecureStops from an empty list.");
             List<byte[]> secureStops = drm.getSecureStops();
@@ -926,4 +949,15 @@
             return "unavailable";
         }
     }
+
+    private boolean watchHasNoClearkeySupport() {
+        if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID)) {
+            if (isWatchDevice()) {
+                return true;
+            } else {
+                throw new Error(ERR_MSG_CRYPTO_SCHEME_NOT_SUPPORTED);
+            }
+        }
+        return false;
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 58d803e..aa31210 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -22,8 +22,13 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.media.MediaDataSource;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Rect;
 import android.support.test.filters.SmallTest;
 import android.platform.test.annotations.RequiresDevice;
 import android.test.AndroidTestCase;
@@ -37,7 +42,11 @@
 import static android.media.MediaMetadataRetriever.OPTION_NEXT_SYNC;
 import static android.media.MediaMetadataRetriever.OPTION_PREVIOUS_SYNC;
 
+import java.io.InputStream;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
 
 @SmallTest
 @RequiresDevice
@@ -49,6 +58,19 @@
     protected MediaMetadataRetriever mRetriever;
     private PackageManager mPackageManager;
 
+    private static int BORDER_WIDTH = 16;
+    private static Color COLOR_BLOCK =
+            Color.valueOf(1.0f, 1.0f, 1.0f);
+    private static Color[] COLOR_BARS = {
+            Color.valueOf(0.0f, 0.0f, 0.0f),
+            Color.valueOf(0.0f, 0.0f, 0.64f),
+            Color.valueOf(0.0f, 0.64f, 0.0f),
+            Color.valueOf(0.0f, 0.64f, 0.64f),
+            Color.valueOf(0.64f, 0.0f, 0.0f),
+            Color.valueOf(0.64f, 0.0f, 0.64f),
+            Color.valueOf(0.64f, 0.64f, 0.0f),
+    };
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -296,6 +318,63 @@
     }
 
     private void testGetFrameAtTime(int option, int[][] testCases) {
+        testGetFrameAt(testCases, (r) -> {
+            List<Bitmap> bitmaps = new ArrayList<>();
+            for (int i = 0; i < testCases.length; i++) {
+                bitmaps.add(r.getFrameAtTime(testCases[i][0], option));
+            }
+            return bitmaps;
+        });
+    }
+
+    public void testGetFrameAtIndex() {
+        int[][] testCases = { { 60, 60 }, { 73, 73 }, { 76, 76 }, { 88, 88 }, { 94, 94} };
+
+        testGetFrameAt(testCases, (r) -> {
+            List<Bitmap> bitmaps = new ArrayList<>();
+            for (int i = 0; i < testCases.length; i++) {
+                bitmaps.add(r.getFrameAtIndex(testCases[i][0]));
+            }
+            return bitmaps;
+        });
+
+        MediaMetadataRetriever.BitmapParams params = new MediaMetadataRetriever.BitmapParams();
+        params.setPreferredConfig(Bitmap.Config.RGB_565);
+        assertEquals("Failed to set preferred config",
+                Bitmap.Config.RGB_565, params.getPreferredConfig());
+
+        testGetFrameAt(testCases, (r) -> {
+            List<Bitmap> bitmaps = new ArrayList<>();
+            for (int i = 0; i < testCases.length; i++) {
+                Bitmap bitmap = r.getFrameAtIndex(testCases[i][0], params);
+                assertEquals(Bitmap.Config.RGB_565, params.getActualConfig());
+                bitmaps.add(bitmap);
+            }
+            return bitmaps;
+        });
+    }
+
+    public void testGetFramesAtIndex() {
+        int[][] testCases = { { 27, 27 }, { 28, 28 }, { 29, 29 }, { 30, 30 }, { 31, 31} };
+
+        testGetFrameAt(testCases, (r) -> {
+            return r.getFramesAtIndex(testCases[0][0], testCases.length);
+        });
+
+        MediaMetadataRetriever.BitmapParams params = new MediaMetadataRetriever.BitmapParams();
+        params.setPreferredConfig(Bitmap.Config.RGB_565);
+        assertEquals("Failed to set preferred config",
+                Bitmap.Config.RGB_565, params.getPreferredConfig());
+
+        testGetFrameAt(testCases, (r) -> {
+            List<Bitmap> bitmaps = r.getFramesAtIndex(testCases[0][0], testCases.length, params);
+            assertEquals(Bitmap.Config.RGB_565, params.getActualConfig());
+            return bitmaps;
+        });
+    }
+
+    private void testGetFrameAt(int[][] testCases,
+            Function<MediaMetadataRetriever, List<Bitmap> > bitmapRetriever) {
         int resId = R.raw.binary_counter_320x240_30fps_600frames;
         if (!MediaUtils.hasCodecForResourceAndDomain(getContext(), resId, "video/")
             && mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
@@ -313,24 +392,23 @@
         } catch (IOException e) {
             fail("Unable to close file");
         }
-        for (int[] testCase : testCases) {
-            getVideoFrameAndVerify(retriever, testCase[0], testCase[1], option);
+
+        List<Bitmap> bitmaps = bitmapRetriever.apply(retriever);
+
+        for (int i = 0; i < testCases.length; i++) {
+            verifyVideoFrame(bitmaps.get(i), testCases[i]);
         }
         retriever.release();
     }
 
-    private void getVideoFrameAndVerify(
-            MediaMetadataRetriever retriever, long timeUs, long expectedCounter, int option) {
+    private void verifyVideoFrame(Bitmap bitmap, int[] testCase) {
         try {
-            Bitmap bitmap = retriever.getFrameAtTime(timeUs, option);
-            if (bitmap == null) {
-                fail("Failed to get bitmap at time " + timeUs + " with option " + option);
-            }
-            assertEquals("Counter value incorrect at time " + timeUs + " with option " + option,
-                    expectedCounter, CodecUtils.readBinaryCounterFromBitmap(bitmap));
+            assertTrue("Failed to get bitmap for " + testCase[0], bitmap != null);
+            assertEquals("Counter value incorrect for " + testCase[0],
+                    testCase[1], CodecUtils.readBinaryCounterFromBitmap(bitmap));
 
             if (SAVE_BITMAP_OUTPUT) {
-                CodecUtils.saveBitmapToFile(bitmap, "test" + timeUs + ".jpg");
+                CodecUtils.saveBitmapToFile(bitmap, "test_" + testCase[0] + ".jpg");
             }
         } catch (Exception e) {
             fail("Exception getting bitmap: " + e);
@@ -518,4 +596,147 @@
             fail("Exception getting bitmap: " + e);
         }
     }
+
+    public void testGetImageAtIndex() throws Exception {
+        if (!MediaUtils.hasDecoder(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+            MediaUtils.skipTest("no video decoders for resource");
+            return;
+        }
+
+        testGetImage(R.raw.heifwriter_input, 1920, 1080, 0 /*rotation*/,
+                4 /*imageCount*/, 3 /*primary*/, true /*useGrid*/, true /*checkColor*/);
+    }
+
+    /**
+     * Determines if two color values are approximately equal.
+     */
+    private static boolean approxEquals(Color expected, Color actual) {
+        final float MAX_DELTA = 0.025f;
+        return (Math.abs(expected.red() - actual.red()) <= MAX_DELTA)
+            && (Math.abs(expected.green() - actual.green()) <= MAX_DELTA)
+            && (Math.abs(expected.blue() - actual.blue()) <= MAX_DELTA);
+    }
+
+    private static Rect getColorBarRect(int index, int width, int height) {
+        int barWidth = (width - BORDER_WIDTH * 2) / COLOR_BARS.length;
+        return new Rect(BORDER_WIDTH + barWidth * index, BORDER_WIDTH,
+                BORDER_WIDTH + barWidth * (index + 1), height - BORDER_WIDTH);
+    }
+
+    private static Rect getColorBlockRect(int index, int width, int height) {
+        int blockCenterX = (width / 5) * (index % 4 + 1);
+        return new Rect(blockCenterX - width / 10, height / 6,
+                        blockCenterX + width / 10, height / 3);
+    }
+
+    private void testGetImage(
+            int resId, int width, int height, int rotation,
+            int imageCount, int primary, boolean useGrid, boolean checkColor)
+                    throws Exception {
+        MediaMetadataRetriever retriever = null;
+        MediaExtractor extractor = null;
+        AssetFileDescriptor afd = null;
+        InputStream inputStream = null;
+
+        try {
+            retriever = new MediaMetadataRetriever();
+
+            Resources resources = getContext().getResources();
+            afd = resources.openRawResourceFd(resId);
+
+            retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+
+            // Verify image related meta keys.
+            String hasImage = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
+            assertTrue("No images found in resId " + resId, "yes".equals(hasImage));
+            assertEquals("Wrong width", width,
+                    Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH)));
+            assertEquals("Wrong height", height,
+                    Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_HEIGHT)));
+            assertEquals("Wrong rotation", rotation,
+                    Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_ROTATION)));
+            assertEquals("Wrong image count", imageCount,
+                    Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
+            assertEquals("Wrong primary index", primary,
+                    Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_PRIMARY)));
+
+            if (checkColor) {
+                Bitmap bitmap = null;
+                // For each image in the image collection, check the 7 color bars' color.
+                // Also check the position of the color block, which should move left-to-right
+                // with the index.
+                for (int imageIndex = 0; imageIndex < imageCount; imageIndex++) {
+                    bitmap = retriever.getImageAtIndex(imageIndex);
+
+                    for (int barIndex = 0; barIndex < COLOR_BARS.length; barIndex++) {
+                        Rect r = getColorBarRect(barIndex, width, height);
+                        assertTrue("Color bar " + barIndex +
+                                " for image " + imageIndex + " doesn't match",
+                                approxEquals(COLOR_BARS[barIndex], Color.valueOf(
+                                        bitmap.getPixel(r.centerX(), r.centerY()))));
+                    }
+
+                    Rect r = getColorBlockRect(imageIndex, width, height);
+                    assertTrue("Color block for image " + imageIndex + " doesn't match",
+                            approxEquals(COLOR_BLOCK, Color.valueOf(
+                                    bitmap.getPixel(r.centerX(), height - r.centerY()))));
+                    bitmap.recycle();
+                }
+
+                // Check the color block position on the primary image.
+                Rect r = getColorBlockRect(primary, width, height);
+                bitmap = retriever.getPrimaryImage();
+                assertTrue("Color block for primary image doesn't match",
+                        approxEquals(COLOR_BLOCK, Color.valueOf(
+                                bitmap.getPixel(r.centerX(), height - r.centerY()))));
+                bitmap.recycle();
+
+                // Check the color block position on the bitmap decoded by BitmapFactory.
+                // This should match the primary image as well.
+                inputStream = getContext().getResources().openRawResource(resId);
+                bitmap = BitmapFactory.decodeStream(inputStream);
+                assertTrue("Color block for bitmap decoding doesn't match",
+                        approxEquals(COLOR_BLOCK, Color.valueOf(
+                                bitmap.getPixel(r.centerX(), height - r.centerY()))));
+                bitmap.recycle();
+            }
+
+            // Check the grid configuration related keys.
+            if (useGrid) {
+                extractor = new MediaExtractor();
+                extractor.setDataSource(
+                        afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+                MediaFormat format = extractor.getTrackFormat(0);
+                int tileWidth = format.getInteger(MediaFormat.KEY_TILE_WIDTH);
+                int tileHeight = format.getInteger(MediaFormat.KEY_TILE_HEIGHT);
+                int gridRows = format.getInteger(MediaFormat.KEY_GRID_ROWS);
+                int gridCols = format.getInteger(MediaFormat.KEY_GRID_COLUMNS);
+                assertTrue("Wrong tile width or grid cols",
+                        ((width + tileWidth - 1) / tileWidth) == gridCols);
+                assertTrue("Wrong tile height or grid rows",
+                        ((height + tileHeight - 1) / tileHeight) == gridRows);
+            }
+        } catch (IOException e) {
+            fail("Unable to open file");
+        } finally {
+            if (retriever != null) {
+                retriever.release();
+            }
+            if (extractor != null) {
+                extractor.release();
+            }
+            if (afd != null) {
+                afd.close();
+            }
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index fcc567b..c169a83 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -104,9 +104,10 @@
 
     public void testSetOnVolumeKeyLongPressListener() throws Exception {
         Context context = getInstrumentation().getTargetContext();
-        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
-            context.getResources().getBoolean(Resources.getSystem().getIdentifier(
-               "config_handleVolumeKeysInWindowManager", "bool", "android"))) {
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                || context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
+                || context.getResources().getBoolean(Resources.getSystem().getIdentifier(
+                        "config_handleVolumeKeysInWindowManager", "bool", "android"))) {
             // Skip this test, because the PhoneWindowManager dispatches volume key
             // events directly to the audio service to change the system volume.
             return;
diff --git a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
index fb5880ea9..dfbced9 100644
--- a/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeMediaDrmClearkeyTest.java
@@ -15,13 +15,11 @@
  */
 package android.media.cts;
 
-import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
+import android.content.pm.PackageManager;
+import android.media.MediaDrm;
 import android.net.Uri;
 import android.util.Log;
 import android.view.Surface;
-import android.view.SurfaceHolder;
 
 import com.android.compatibility.common.util.ApiLevelUtil;
 import com.android.compatibility.common.util.MediaUtils;
@@ -29,9 +27,11 @@
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.UUID;
 
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
 /**
  * Tests MediaDrm NDK APIs. ClearKey system uses a subset of NDK APIs,
  * this test only tests the APIs that are supported by ClearKey system.
@@ -96,10 +96,24 @@
         super.tearDown();
     }
 
+    private boolean watchHasNoClearkeySupport() {
+        if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID)) {
+            if (isWatchDevice()) {
+                return true;
+            } else {
+                throw new Error("Crypto scheme is not supported");
+            }
+        }
+        return false;
+    }
+
+    private boolean isWatchDevice() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
+
     private boolean deviceHasMediaDrm() {
         // ClearKey is introduced after KitKat.
         if (ApiLevelUtil.isAtMost(android.os.Build.VERSION_CODES.KITKAT)) {
-            Log.i(TAG, "This test is designed to work after Android KitKat.");
             return false;
         }
         return true;
@@ -113,6 +127,10 @@
     }
 
     public void testIsCryptoSchemeSupported() throws Exception {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         assertTrue(isCryptoSchemeSupportedNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID)));
         assertTrue(isCryptoSchemeSupportedNative(uuidByteArray(CLEARKEY_SCHEME_UUID)));
     }
@@ -128,16 +146,28 @@
     }
 
     public void testQueryKeyStatus() throws Exception {
-        assertTrue(testQueryKeyStatusNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID)));
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        assertTrue(testQueryKeyStatusNative(uuidByteArray(CLEARKEY_SCHEME_UUID)));
     }
 
     public void testFindSessionId() throws Exception {
-        assertTrue(testFindSessionIdNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID)));
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
+        assertTrue(testFindSessionIdNative(uuidByteArray(CLEARKEY_SCHEME_UUID)));
     }
 
     public void testGetPropertyString() throws Exception {
+        if (watchHasNoClearkeySupport()) {
+            return;
+        }
+
         StringBuffer value = new StringBuffer();
-        testGetPropertyStringNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID), "description", value);
+        testGetPropertyStringNative(uuidByteArray(CLEARKEY_SCHEME_UUID), "description", value);
         assertEquals("ClearKey CDM", value.toString());
 
         value.delete(0, value.length());
@@ -149,7 +179,7 @@
         StringBuffer value = new StringBuffer();
 
         try {
-            testGetPropertyStringNative(uuidByteArray(COMMON_PSSH_SCHEME_UUID),
+            testGetPropertyStringNative(uuidByteArray(CLEARKEY_SCHEME_UUID),
                     "unknown-property", value);
             fail("Should have thrown an exception");
         } catch (RuntimeException e) {
@@ -175,8 +205,8 @@
             UUID drmSchemeUuid, String mimeType, /*String initDataType,*/ Uri audioUrl, Uri videoUrl,
             int videoWidth, int videoHeight) throws Exception {
 
-        if (!isCryptoSchemeSupportedNative(uuidByteArray(drmSchemeUuid))) {
-            throw new Error("Crypto scheme is not supported.");
+        if (isWatchDevice()) {
+            return;
         }
 
         IConnectionStatus connectionStatus = new ConnectionStatus(mContext);
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 82cd778..3ef70d8 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1054,6 +1054,7 @@
     float* data = static_cast<float*>(
         glMapBufferRange(GL_ARRAY_BUFFER, 0, desc.width,
                          GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
+    ASSERT_NE(data, nullptr) << "glMapBufferRange on a blob buffer failed";
     memcpy(data, kQuadPositions, desc.width);
     glUnmapBuffer(GL_ARRAY_BUFFER);
     glFinish();
diff --git a/tests/tests/net/src/android/net/cts/DnsTest.java b/tests/tests/net/src/android/net/cts/DnsTest.java
index 8575c33..84231c2 100644
--- a/tests/tests/net/src/android/net/cts/DnsTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsTest.java
@@ -19,6 +19,9 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
+import android.net.Network;
 import android.net.NetworkInfo;
 import android.os.SystemClock;
 import android.test.AndroidTestCase;
@@ -29,6 +32,8 @@
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class DnsTest extends AndroidTestCase {
 
@@ -40,6 +45,12 @@
     private static final String TAG = "DnsTest";
     private static final String PROXY_NETWORK_TYPE = "PROXY";
 
+    private ConnectivityManager mCm;
+
+    public void setUp() {
+        mCm = getContext().getSystemService(ConnectivityManager.class);
+    }
+
     /**
      * @return true on success
      */
@@ -57,7 +68,9 @@
      * Perf - measure size of first and second tier caches and their effect
      * Assert requires network permission
      */
-    public void testDnsWorks() {
+    public void testDnsWorks() throws Exception {
+        ensureIpv6Connectivity();
+
         InetAddress addrs[] = {};
         try {
             addrs = InetAddress.getAllByName("www.google.com");
@@ -88,11 +101,14 @@
         try {
             addrs = InetAddress.getAllByName("ipv6.google.com");
         } catch (UnknownHostException e) {}
-        assertTrue("[RERUN] DNS could not resolve ipv6.google.com, check the network supports IPv6",
-                addrs.length != 0);
+        String msg =
+            "[RERUN] DNS could not resolve ipv6.google.com, check the network supports IPv6. lp=" +
+            mCm.getActiveLinkProperties();
+        assertTrue(msg, addrs.length != 0);
         for (InetAddress addr : addrs) {
-            assertFalse ("[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() +
-                    ", check your network's DNS server", addr instanceof Inet4Address);
+            msg = "[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() +
+                    ", check your network's DNS server. lp=" + mCm.getActiveLinkProperties();
+            assertFalse (msg, addr instanceof Inet4Address);
             foundV6 |= (addr instanceof Inet6Address);
             if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString());
         }
@@ -256,13 +272,35 @@
     }
 
     private boolean activeNetworkInfoIsProxy() {
-        ConnectivityManager cm = (ConnectivityManager)
-                getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkInfo info = cm.getActiveNetworkInfo();
+        NetworkInfo info = mCm.getActiveNetworkInfo();
         if (PROXY_NETWORK_TYPE.equals(info.getTypeName())) {
             return true;
         }
 
         return false;
     }
+
+    private void ensureIpv6Connectivity() throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        final int TIMEOUT_MS = 5_000;
+
+        final NetworkCallback callback = new NetworkCallback() {
+            @Override
+            public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
+                if (lp.hasGlobalIPv6Address()) {
+                    latch.countDown();
+                }
+            }
+        };
+        mCm.registerDefaultNetworkCallback(callback);
+
+        String msg = "Default network did not provide IPv6 connectivity after " + TIMEOUT_MS
+                + "ms. Please connect to an IPv6-capable network. lp="
+                + mCm.getActiveLinkProperties();
+        try {
+            assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } finally {
+            mCm.unregisterNetworkCallback(callback);
+        }
+    }
 }
diff --git a/tests/tests/packageinstaller/externalsources/Android.mk b/tests/tests/packageinstaller/externalsources/Android.mk
index 05e43ca..b7346b5 100755
--- a/tests/tests/packageinstaller/externalsources/Android.mk
+++ b/tests/tests/packageinstaller/externalsources/Android.mk
@@ -24,12 +24,14 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator android-support-test androidx.legacy_legacy-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator \
+                               android-support-test \
+                               androidx.legacy_legacy-support-v4 \
+                               compatibility-device-util
 
 LOCAL_SDK_VERSION := current
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 include $(BUILD_CTS_PACKAGE)
-
diff --git a/tests/tests/packageinstaller/externalsources/AndroidManifest.xml b/tests/tests/packageinstaller/externalsources/AndroidManifest.xml
index 8bcdd04..728ac72 100755
--- a/tests/tests/packageinstaller/externalsources/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/externalsources/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.packageinstaller.externalsources.cts" >
+          package="android.packageinstaller.externalsources.cts"
+          android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
 
diff --git a/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesInstantAppsTest.java b/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesInstantAppsTest.java
new file mode 100644
index 0000000..7aa6a57
--- /dev/null
+++ b/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesInstantAppsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.packageinstaller.externalsources.cts;
+
+import static org.junit.Assert.assertFalse;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.AppModeInstant;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.AppOpsUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@AppModeInstant
+public class ExternalSourcesInstantAppsTest {
+
+    private Context mContext;
+    private PackageManager mPm;
+    private String mPackageName;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mPm = mContext.getPackageManager();
+        mPackageName = mContext.getPackageName();
+    }
+
+    private void setAppOpsMode(int mode) throws IOException {
+        AppOpsUtils.setOpMode(mPackageName, "REQUEST_INSTALL_PACKAGES", mode);
+    }
+
+    @Test
+    public void blockedSourceTest() throws Exception {
+        setAppOpsMode(AppOpsManager.MODE_ERRORED);
+        final boolean isTrusted = mPm.canRequestPackageInstalls();
+        assertFalse("Instant app " + mPackageName + " allowed to install packages", isTrusted);
+    }
+
+    @Test
+    public void allowedSourceTest() throws Exception {
+        setAppOpsMode(AppOpsManager.MODE_ALLOWED);
+        final boolean isTrusted = mPm.canRequestPackageInstalls();
+        assertFalse("Instant app " + mPackageName + " allowed to install packages", isTrusted);
+    }
+
+    @Test
+    public void defaultSourceTest() throws Exception {
+        setAppOpsMode(AppOpsManager.MODE_DEFAULT);
+        final boolean isTrusted = mPm.canRequestPackageInstalls();
+        assertFalse("Instant app " + mPackageName + " allowed to install packages", isTrusted);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        setAppOpsMode(AppOpsManager.MODE_DEFAULT);
+    }
+}
diff --git a/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesTest.java b/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesTest.java
index 06e858e..a29264b 100644
--- a/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesTest.java
+++ b/tests/tests/packageinstaller/externalsources/src/android/packageinstaller/externalsources/cts/ExternalSourcesTest.java
@@ -19,6 +19,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -35,6 +36,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@AppModeFull
 public class ExternalSourcesTest {
 
     private Context mContext;
diff --git a/tests/tests/permission/src/android/permission/cts/NoKeyPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoKeyPermissionTest.java
index 8ed9143..5a0b259 100644
--- a/tests/tests/permission/src/android/permission/cts/NoKeyPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoKeyPermissionTest.java
@@ -32,7 +32,9 @@
     protected void setUp() throws Exception {
         super.setUp();
         mKeyManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        mKeyLock = mKeyManager.newKeyguardLock("testTag");
+        if (mKeyManager != null) {
+            mKeyLock = mKeyManager.newKeyguardLock("testTag");
+        }
     }
 
     /**
@@ -42,6 +44,10 @@
      */
     @SmallTest
     public void testDisableKeyguard() {
+        // KeyguardManager was not accessible, pass.
+        if (mKeyManager == null) {
+            return;
+        }
         try {
             mKeyLock.disableKeyguard();
             fail("KeyguardManager.KeyguardLock.disableKeyguard did not throw SecurityException as"
@@ -58,6 +64,10 @@
      */
     @SmallTest
     public void testReenableKeyguard() {
+        // KeyguardManager was not accessible, pass.
+        if (mKeyManager == null) {
+            return;
+        }
         try {
             mKeyLock.reenableKeyguard();
             fail("KeyguardManager.KeyguardLock.reenableKeyguard did not throw SecurityException as"
@@ -74,6 +84,10 @@
      */
     @SmallTest
     public void testExitKeyguardSecurely() {
+        // KeyguardManager was not accessible, pass.
+        if (mKeyManager == null) {
+            return;
+        }
         try {
             mKeyManager.exitKeyguardSecurely(null);
             fail("KeyguardManager.exitKeyguardSecurely did not throw SecurityException as"
diff --git a/tests/tests/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
index 9180c77..0ccebed 100644
--- a/tests/tests/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.os.Vibrator;
+import android.platform.test.annotations.AppModeFull;
 import android.telephony.gsm.SmsManager;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -82,6 +83,7 @@
      *   {@link android.Manifest.permission#SET_WALLPAPER}.
      * @throws IOException 
      */
+    @AppModeFull(reason = "Instant apps cannot access the WallpaperManager")
     @SmallTest
     public void testSetWallpaper() throws IOException {
         if (!WallpaperManager.getInstance(mContext).isWallpaperSupported()) {
diff --git a/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
index ec11a0c..fd7e977 100644
--- a/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
@@ -22,6 +22,7 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.PowerManager;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -45,6 +46,7 @@
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#WAKE_LOCK}.
      */
+    @AppModeFull(reason = "Instant apps cannot access the WifiManager")
     @SmallTest
     public void testWifiLockAcquire() {
         final WifiManager wifiManager = (WifiManager) mContext.getSystemService(
diff --git a/tests/tests/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java b/tests/tests/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java
index ad32923..df1a42c 100644
--- a/tests/tests/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java
@@ -24,6 +24,7 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.PowerManager;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -36,6 +37,7 @@
 /**
  * Verify that Wallpaper-related operations enforce the correct permissions.
  */
+@AppModeFull(reason = "instant apps cannot access the WallpaperManager")
 public class NoWallpaperPermissionsTest extends AndroidTestCase {
     private WallpaperManager mWM;
 
diff --git a/tests/tests/permission/src/android/permission/cts/NoWifiStatePermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoWifiStatePermissionTest.java
index 0804ebe..d8acd50 100644
--- a/tests/tests/permission/src/android/permission/cts/NoWifiStatePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoWifiStatePermissionTest.java
@@ -19,12 +19,14 @@
 import android.content.Context;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Verify WifiManager related methods without specific Wifi state permissions.
  */
+@AppModeFull(reason = "Instant apps cannot access the WifiManager")
 @SmallTest
 public class NoWifiStatePermissionTest extends AndroidTestCase {
     private static final int TEST_NET_ID = 1;
diff --git a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
index 909ac35..ec0de49 100644
--- a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
@@ -21,6 +21,8 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.CallLog;
 import android.provider.Contacts;
 import android.provider.Settings;
@@ -55,11 +57,28 @@
                 android.Manifest.permission.WRITE_CONTACTS);
     }
 
+    public void assertWritingContentUriRequiresPermission(Uri uri, String permission,
+            boolean allowIAE) {
+        try {
+            getContext().getContentResolver().insert(uri, new ContentValues());
+            fail("expected SecurityException requiring " + permission);
+        } catch (IllegalArgumentException e) {
+            if (!allowIAE) {
+                fail("expected SecurityException requiring " + permission + " got " + e);
+            }
+        } catch (SecurityException expected) {
+            assertNotNull("security exception's error message.", expected.getMessage());
+            assertTrue("error message should contain " + permission + ".",
+                    expected.getMessage().contains(permission));
+        }
+    }
+
     /**
      * Verify that reading call logs requires permissions.
      * <p>Tests Permission:
      *   {@link android.Manifest.permission#READ_CALL_LOG}
      */
+    @AppModeFull
     public void testReadCallLog() {
         assertReadingContentUriRequiresPermission(CallLog.CONTENT_URI,
                 android.Manifest.permission.READ_CALL_LOG);
@@ -72,7 +91,8 @@
      */
     public void testWriteCallLog() {
         assertWritingContentUriRequiresPermission(CallLog.CONTENT_URI,
-                android.Manifest.permission.WRITE_CALL_LOG);
+                android.Manifest.permission.WRITE_CALL_LOG,
+                getContext().getPackageManager().isInstantApp());
     }
 
     /**
diff --git a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
new file mode 100644
index 0000000..736cf2f
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.permission.cts;
+
+import static android.content.Context.DEVICE_POLICY_SERVICE;
+import static android.content.Context.FINGERPRINT_SERVICE;
+import static android.content.Context.SHORTCUT_SERVICE;
+import static android.content.Context.USB_SERVICE;
+import static android.content.Context.WALLPAPER_SERVICE;
+import static android.content.Context.WIFI_AWARE_SERVICE;
+import static android.content.Context.WIFI_P2P_SERVICE;
+import static android.content.Context.WIFI_SERVICE;
+
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
+import android.platform.test.annotations.AppModeInstant;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Some services are not available to instant apps, see {@link Context#getSystemService}.
+ */
+@AppModeInstant
+@RunWith(AndroidJUnit4.class)
+public class ServicesInstantAppsCannotAccessTests {
+    @Test
+    public void cannotGetDevicePolicyManager() {
+    assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+            DEVICE_POLICY_SERVICE));
+    }
+
+    @Test
+    public void cannotGetFingerprintManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                FINGERPRINT_SERVICE));
+    }
+
+    @Test
+    public void cannotGetShortcutManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                SHORTCUT_SERVICE));
+    }
+
+    @Test
+    public void cannotGetUsbManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                USB_SERVICE));
+    }
+
+    @Test
+    public void cannotGetWallpaperManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                WALLPAPER_SERVICE));
+    }
+
+    @Test
+    public void cannotGetWifiP2pManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                WIFI_P2P_SERVICE));
+    }
+
+    @Test
+    public void cannotGetWifiManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                WIFI_SERVICE));
+    }
+
+    @Test
+    public void cannotGetWifiAwareManager() {
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                WIFI_AWARE_SERVICE));
+    }
+}
diff --git a/tests/tests/print/printTestUtilLib/src/android/print/test/BasePrintTest.java b/tests/tests/print/printTestUtilLib/src/android/print/test/BasePrintTest.java
old mode 100644
new mode 100755
index dc4ae9d..5c40dfc
--- a/tests/tests/print/printTestUtilLib/src/android/print/test/BasePrintTest.java
+++ b/tests/tests/print/printTestUtilLib/src/android/print/test/BasePrintTest.java
@@ -199,13 +199,6 @@
 
         Instrumentation instrumentation = getInstrumentation();
 
-        // Prevent rotation
-        getUiDevice().freezeRotation();
-        while (!getUiDevice().isNaturalOrientation()) {
-            getUiDevice().setOrientationNatural();
-            getUiDevice().waitForIdle();
-        }
-
         // Make sure we start with a clean slate.
         Log.d(LOG_TAG, "clearPrintSpoolerData()");
         clearPrintSpoolerData();
@@ -270,6 +263,13 @@
         assumeTrue(getInstrumentation().getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_PRINTING));
 
+        // Prevent rotation
+        getUiDevice().freezeRotation();
+        while (!getUiDevice().isNaturalOrientation()) {
+            getUiDevice().setOrientationNatural();
+            getUiDevice().waitForIdle();
+        }
+
         // Initialize the latches.
         Log.d(LOG_TAG, "init counters");
         mCancelOperationCounter = new CallCounter();
@@ -302,6 +302,9 @@
 
         sIdToTest.remove(mTestId);
 
+        // Allow rotation
+        getUiDevice().unfreezeRotation();
+
         Log.d(LOG_TAG, "tearDown() done");
     }
 
@@ -324,9 +327,6 @@
         SystemUtil.runShellCommand(instrumentation, "settings put secure "
                     + Settings.Secure.DISABLED_PRINT_SERVICES + " null");
 
-        // Allow rotation
-        getUiDevice().unfreezeRotation();
-
         Log.d(LOG_TAG, "tearDownClass() done");
     }
 
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
index 37e7a10..c9b40f4 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
@@ -24,7 +24,9 @@
 LOCAL_MODULE_TAGS := optional
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	ctstestrunner \
+	compatibility-device-util
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SDK_VERSION := current
 LOCAL_JAVA_LIBRARIES += android.test.runner
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk b/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
index 684cb10..a064bc7 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
Binary files differ
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
index 3727c60..9fe37ea 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
@@ -18,20 +18,30 @@
 
 package android.omapi.accesscontrol1.cts;
 
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeoutException;
 
+import android.content.pm.PackageManager;
 import android.os.RemoteException;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
 import android.se.omapi.SEService.OnConnectedListener;
 import android.se.omapi.Session;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
 
-public class AccessControlTest extends AndroidTestCase {
+import com.android.compatibility.common.util.PropertyUtil;
+
+public class AccessControlTest {
     private final static String UICC_READER_PREFIX = "SIM";
     private final static String ESE_READER_PREFIX = "eSE";
     private final static String SD_READER_PREFIX = "SD";
@@ -144,15 +154,22 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        seService = new SEService(getContext(), new SynchronousExecutor(), mListener);
+    private boolean supportsHardware() {
+        final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(supportsHardware());
+        seService = new SEService(InstrumentationRegistry.getContext(), new SynchronousExecutor(), mListener);
         connectionTimer = new Timer();
         connectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (seService != null && seService.isConnected()) {
             seService.shutdown();
             connected = false;
@@ -179,36 +196,42 @@
         }
     }
 
+    @Test
     public void testAuthorizedAID() {
         for (byte[] aid : AUTHORIZED_AID) {
             testSelectableAid(aid);
         }
     }
 
+    @Test
     public void testUnauthorizedAID() {
         for (byte[] aid : UNAUTHORIZED_AID) {
             testUnauthorisedAid(aid);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID40() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_40) {
             testTransmitAPDU(AID_40, apdu);
         }
     }
 
+    @Test
     public void testUnauthorisedAPDUAID40() {
         for (byte[] apdu : UNAUTHORIZED_APDU_AID_40) {
             testUnauthorisedAPDU(AID_40, apdu);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID41() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_41) {
             testTransmitAPDU(AID_41, apdu);
         }
     }
 
+    @Test
     public void testUnauthorisedAPDUAID41() {
         for (byte[] apdu : UNAUTHORIZED_APDU_AID_41) {
             testUnauthorisedAPDU(AID_41, apdu);
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
index 2e9b107..eff645d 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
@@ -24,7 +24,9 @@
 LOCAL_MODULE_TAGS := optional
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+       ctstestrunner \
+       compatibility-device-util
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SDK_VERSION := current
 LOCAL_JAVA_LIBRARIES += android.test.runner
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk b/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
index 282805e..71c57e9 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
Binary files differ
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
index 8b51205..74021c3 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
@@ -18,20 +18,30 @@
 
 package android.omapi.accesscontrol2.cts;
 
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeoutException;
 
+import android.content.pm.PackageManager;
 import android.os.RemoteException;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
 import android.se.omapi.SEService.OnConnectedListener;
 import android.se.omapi.Session;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
 
-public class AccessControlTest extends AndroidTestCase {
+import com.android.compatibility.common.util.PropertyUtil;
+
+public class AccessControlTest {
     private final static String UICC_READER_PREFIX = "SIM";
     private final static String ESE_READER_PREFIX = "eSE";
     private final static String SD_READER_PREFIX = "SD";
@@ -143,15 +153,22 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        seService = new SEService(getContext(), new SynchronousExecutor(), mListener);
+    private boolean supportsHardware() {
+        final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(supportsHardware());
+        seService = new SEService(InstrumentationRegistry.getContext(), new SynchronousExecutor(), mListener);
         connectionTimer = new Timer();
         connectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (seService != null && seService.isConnected()) {
             seService.shutdown();
             connected = false;
@@ -178,36 +195,42 @@
         }
     }
 
+    @Test
     public void testAuthorizedAID() {
         for (byte[] aid : AUTHORIZED_AID) {
             testSelectableAid(aid);
         }
     }
 
+    @Test
     public void testUnauthorizedAID() {
         for (byte[] aid : UNAUTHORIZED_AID) {
             testUnauthorisedAid(aid);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID40() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_40) {
             testTransmitAPDU(AID_40, apdu);
         }
     }
 
+    @Test
     public void testUnauthorisedAPDUAID40() {
         for (byte[] apdu : UNAUTHORIZED_APDU_AID_40) {
             testUnauthorisedAPDU(AID_40, apdu);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID41() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_41) {
             testTransmitAPDU(AID_41, apdu);
         }
     }
 
+    @Test
     public void testUnauthorisedAPDUAID41() {
         for (byte[] apdu : UNAUTHORIZED_APDU_AID_41) {
             testUnauthorisedAPDU(AID_41, apdu);
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
index cd3f132..29e38f3 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
@@ -24,7 +24,9 @@
 LOCAL_MODULE_TAGS := optional
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	ctstestrunner \
+	compatibility-device-util
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_SDK_VERSION := current
 LOCAL_JAVA_LIBRARIES += android.test.runner
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk b/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
index 2f182e5..647b485 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
Binary files differ
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
index 5ca0c51..51483e9 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
@@ -18,20 +18,30 @@
 
 package android.omapi.accesscontrol3.cts;
 
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeoutException;
 
+import android.content.pm.PackageManager;
 import android.os.RemoteException;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
 import android.se.omapi.SEService.OnConnectedListener;
 import android.se.omapi.Session;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
 
-public class AccessControlTest extends AndroidTestCase {
+import com.android.compatibility.common.util.PropertyUtil;
+
+public class AccessControlTest {
     private final static String UICC_READER_PREFIX = "SIM";
     private final static String ESE_READER_PREFIX = "eSE";
     private final static String SD_READER_PREFIX = "SD";
@@ -153,15 +163,22 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        seService = new SEService(getContext(), new SynchronousExecutor(), mListener);
+    private boolean supportsHardware() {
+        final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(supportsHardware());
+        seService = new SEService(InstrumentationRegistry.getContext(), new SynchronousExecutor(), mListener);
         connectionTimer = new Timer();
         connectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (seService != null && seService.isConnected()) {
             seService.shutdown();
             connected = false;
@@ -188,30 +205,35 @@
         }
     }
 
+    @Test
     public void testAuthorizedAID() {
         for (byte[] aid : AUTHORIZED_AID) {
             testSelectableAid(aid);
         }
     }
 
+    @Test
     public void testUnauthorizedAID() {
         for (byte[] aid : UNAUTHORIZED_AID) {
             testUnauthorisedAid(aid);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID40() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_40) {
             testTransmitAPDU(AID_40, apdu);
         }
     }
 
+    @Test
     public void testAuthorizedAPDUAID41() {
         for (byte[] apdu : AUTHORIZED_APDU_AID_41) {
             testTransmitAPDU(AID_41, apdu);
         }
     }
 
+    @Test
     public void testUnauthorisedAPDUAID41() {
         for (byte[] apdu : UNAUTHORIZED_APDU_AID_41) {
             testUnauthorisedAPDU(AID_41, apdu);
diff --git a/tests/tests/secure_element/omapi/Android.mk b/tests/tests/secure_element/omapi/Android.mk
index f12aa75..4378136 100644
--- a/tests/tests/secure_element/omapi/Android.mk
+++ b/tests/tests/secure_element/omapi/Android.mk
@@ -24,7 +24,9 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	ctstestrunner \
+	compatibility-device-util
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
index e6a3456..34b6411 100644
--- a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
+++ b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
@@ -18,6 +18,13 @@
 
 package android.omapi.cts;
 
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -28,14 +35,17 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeoutException;
 
+import android.content.pm.PackageManager;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
 import android.se.omapi.SEService.OnConnectedListener;
 import android.se.omapi.Session;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
 
-public class OmapiTest extends AndroidTestCase {
+import com.android.compatibility.common.util.PropertyUtil;
+
+public class OmapiTest {
 
     private final static String UICC_READER_PREFIX = "SIM";
     private final static String ESE_READER_PREFIX = "eSE";
@@ -136,20 +146,27 @@
         }
     }
 
+    private boolean supportsHardware() {
+        final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+    }
+
     private void assertGreaterOrEqual(long greater, long lesser) {
         assertTrue("" + greater + " expected to be greater than or equal to " + lesser,
                 greater >= lesser);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        seService = new SEService(getContext(), new SynchronousExecutor(), mListener);
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(supportsHardware());
+        seService = new SEService(InstrumentationRegistry.getContext(), new SynchronousExecutor(), mListener);
         connectionTimer = new Timer();
         connectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (seService != null && seService.isConnected()) {
             seService.shutdown();
             connected = false;
@@ -177,6 +194,7 @@
     }
 
     /** Tests getReaders API */
+    @Test
     public void testGetReaders() {
         try {
             waitForConnection();
@@ -197,6 +215,7 @@
     }
 
     /** Tests getATR API */
+    @Test
     public void testATR() {
         try {
             waitForConnection();
@@ -228,6 +247,7 @@
     }
 
     /** Tests OpenBasicChannel API when aid is null */
+    @Test
     public void testOpenBasicChannelNullAid() {
         try {
             waitForConnection();
@@ -253,6 +273,7 @@
     }
 
     /** Tests OpenBasicChannel API when aid is provided */
+    @Test
     public void testOpenBasicChannelNonNullAid() {
         try {
             waitForConnection();
@@ -278,10 +299,12 @@
     }
 
     /** Tests Select API */
+    @Test
     public void testSelectableAid() {
         testSelectableAid(SELECTABLE_AID);
     }
 
+    @Test
     public void testLongSelectResponse() {
         byte[] selectResponse = testSelectableAid(LONG_SELECT_RESPONSE_AID);
         if (selectResponse == null) {
@@ -318,6 +341,7 @@
     }
 
     /** Tests if NoSuchElementException in Select */
+    @Test
     public void testWrongAid() {
         try {
             waitForConnection();
@@ -330,7 +354,7 @@
         }
     }
 
-    public void testNonSelectableAid(Reader reader, byte[] aid) {
+    private void testNonSelectableAid(Reader reader, byte[] aid) {
         boolean exception = false;
         Session session = null;
         try {
@@ -350,6 +374,7 @@
     }
 
     /** Tests if Security Exception in Transmit */
+    @Test
     public void testSecurityExceptionInTransmit() {
         boolean exception = false;
         Session session;
@@ -412,6 +437,7 @@
      * Checks the return status and verifies the size of the
      * response.
      */
+    @Test
     public void testTransmitApdu() {
         try {
             waitForConnection();
@@ -446,6 +472,7 @@
      * - the warning code is properly received by the application layer as SW answer
      * - the verify that the application layer can fetch the additionnal data (when present)
      */
+    @Test
     public void testStatusWordTransmit() {
         try {
             waitForConnection();
@@ -491,6 +518,7 @@
     }
 
     /** Test if the responses are segmented by the underlying implementation */
+    @Test
     public void testSegmentedResponseTransmit() {
         try {
             waitForConnection();
@@ -514,6 +542,7 @@
     }
 
     /** Test the P2 value of the select command sent by the underlying implementation */
+    @Test
     public void testP2Value() {
         try {
             waitForConnection();
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index e64c1b4..e903ab7 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -263,18 +263,14 @@
      * set up to overflow iov[OVERFLOW_BUF] on non-atomic redo in kernel
      * function pipe_iov_copy_to_user
      */
-    iovs[OVERFLOW_BUF - 1].iov_len = IOV_LEN*10;
-    iovs[OVERFLOW_BUF].iov_base = bufs[OVERFLOW_BUF];
-    iovs[OVERFLOW_BUF].iov_len = IOV_LEN;
-
-    overflow_addr = mmap((void *) FIXED_ADDR, PAGE_SIZE, PROT_READ | PROT_WRITE,
-            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-
-    bufs[OVERFLOW_BUF] = overflow_addr;
+    bufs[OVERFLOW_BUF] = mmap((void*)(FIXED_ADDR), PAGE_SIZE, PROT_READ | PROT_WRITE,
+            MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
     if (bufs[OVERFLOW_BUF] == MAP_FAILED) {
         ALOGE("mmap fixed addr failed:%s", strerror(errno));
         goto __close_pipe;
     }
+    iovs[OVERFLOW_BUF].iov_base = bufs[OVERFLOW_BUF];
+    iovs[OVERFLOW_BUF].iov_len = IOV_LEN;
 
     for (i = 0; i < BUFS; i++) {
         if (i == OVERFLOW_BUF) {
diff --git a/tests/tests/security/res/raw/bug_33298089_avc.mp4 b/tests/tests/security/res/raw/bug_33298089_avc.mp4
new file mode 100644
index 0000000..e36f3ae
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_33298089_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_35472997.mp4 b/tests/tests/security/res/raw/bug_35472997.mp4
new file mode 100644
index 0000000..9cd0c67
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_35472997.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_36492741.mp4 b/tests/tests/security/res/raw/bug_36492741.mp4
new file mode 100644
index 0000000..830724d
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_36492741.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_36993291_avc.mp4 b/tests/tests/security/res/raw/bug_36993291_avc.mp4
new file mode 100644
index 0000000..2b5dbc1
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_36993291_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_69269702.mp4 b/tests/tests/security/res/raw/bug_69269702.mp4
new file mode 100644
index 0000000..ae11796
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_69269702.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
new file mode 100644
index 0000000..dc74708
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 The AndroCid Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.test.AndroidTestCase;
+
+import android.app.Activity;
+import android.os.BaseBundle;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.annotation.SuppressLint;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.Random;
+
+import android.security.cts.R;
+import android.platform.test.annotations.SecurityTest;
+
+public class AmbiguousBundlesTest extends AndroidTestCase {
+
+    @SecurityTest
+    public void test_android_CVE_2017_13287() throws Exception {
+        Bundle bundle;
+        {
+            Bundle verifyMe = new Bundle();
+            verifyMe.putString("cmd", "something_safe");
+            Bundle useMe = new Bundle();
+            useMe.putString("cmd", "replaced_thing");
+            Ambiguator a = new Ambiguator() {
+                @Override
+                public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
+                    Random random = new Random(1234);
+                    int minHash = 0;
+                    for (String s : preReSerialize.keySet()) {
+                        minHash = Math.min(minHash, s.hashCode());
+                    }
+                    for (String s : postReSerialize.keySet()) {
+                        minHash = Math.min(minHash, s.hashCode());
+                    }
+
+                    String key;
+                    int keyHash;
+
+                    do {
+                        key = randomString(random);
+                        keyHash = key.hashCode();
+                    } while (keyHash >= minHash);
+
+                    padBundle(postReSerialize, preReSerialize.size() + 1, minHash, random);
+                    padBundle(preReSerialize, postReSerialize.size() - 1, minHash, random);
+
+                    String key2;
+                    int key2Hash;
+                    do {
+                        key2 = makeStringToInject(postReSerialize, random);
+                        key2Hash = key2.hashCode();
+                    } while (key2Hash >= minHash || key2Hash <= keyHash);
+
+
+                    Parcel parcel = Parcel.obtain();
+
+                    parcel.writeInt(preReSerialize.size() + 2);
+                    parcel.writeString(key);
+
+                    parcel.writeInt(VAL_PARCELABLE);
+                    parcel.writeString("com.android.internal.widget.VerifyCredentialResponse");
+
+                    parcel.writeInt(0);
+                    parcel.writeInt(0);
+
+                    parcel.writeString(key2);
+                    parcel.writeInt(VAL_NULL);
+
+                    writeBundleSkippingHeaders(parcel, preReSerialize);
+
+                    parcel.setDataPosition(0);
+                    Bundle bundle = new Bundle();
+                    parcelledDataField.set(bundle, parcel);
+                    return bundle;
+                }
+
+                @Override
+                protected String makeStringToInject(Bundle stuffToInject, Random random) {
+                    Parcel p = Parcel.obtain();
+                    p.writeInt(0);
+                    p.writeInt(0);
+
+                    Parcel p2 = Parcel.obtain();
+                    stuffToInject.writeToParcel(p2, 0);
+                    int p2Len = p2.dataPosition() - BUNDLE_SKIP;
+
+                    for (int i = 0; i < p2Len / 4 + 4; i++) {
+                        int paddingVal;
+                        if (i > 3) {
+                            paddingVal = i;
+                        } else {
+                            paddingVal = random.nextInt();
+                        }
+                        p.writeInt(paddingVal);
+
+                    }
+
+                    p.appendFrom(p2, BUNDLE_SKIP, p2Len);
+                    p2.recycle();
+
+                    while (p.dataPosition() % 8 != 0) p.writeInt(0);
+                    for (int i = 0; i < 2; i++) {
+                        p.writeInt(0);
+                    }
+
+                    int len = p.dataPosition() / 2 - 1;
+                    p.writeInt(0); p.writeInt(0);
+                    p.setDataPosition(0);
+                    p.writeInt(len);
+                    p.writeInt(len);
+                    p.setDataPosition(0);
+                    String result = p.readString();
+                    p.recycle();
+                    return result;
+                }
+            };
+            bundle = a.make(verifyMe, useMe);
+        }
+
+        bundle = reparcel(bundle);
+        String value1 = bundle.getString("cmd");
+        bundle = reparcel(bundle);
+        String value2 = bundle.getString("cmd");
+
+        if (!value1.equals(value2)) {
+            fail("String " + value1 + "!=" + value2 + " after reparceling.");
+        }
+    }
+
+    @SuppressLint("ParcelClassLoader")
+    private Bundle reparcel(Bundle source) {
+        Parcel p = Parcel.obtain();
+        p.writeBundle(source);
+        p.setDataPosition(0);
+        Bundle copy = p.readBundle();
+        p.recycle();
+        return copy;
+    }
+
+    static abstract class Ambiguator {
+
+        protected static final int VAL_PARCELABLE = 4;
+        protected static final int VAL_NULL = -1;
+        protected static final int BUNDLE_SKIP = 12;
+
+        protected final Field parcelledDataField;
+
+        public Ambiguator() throws Exception {
+            parcelledDataField = BaseBundle.class.getDeclaredField("mParcelledData");
+            parcelledDataField.setAccessible(true);
+        }
+
+        abstract public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception;
+
+        abstract protected String makeStringToInject(Bundle stuffToInject, Random random);
+
+        protected static void writeBundleSkippingHeaders(Parcel parcel, Bundle bundle) {
+            Parcel p2 = Parcel.obtain();
+            bundle.writeToParcel(p2, 0);
+            parcel.appendFrom(p2, BUNDLE_SKIP, p2.dataPosition() - BUNDLE_SKIP);
+            p2.recycle();
+        }
+
+        protected static String randomString(Random random) {
+            StringBuilder b = new StringBuilder();
+            for (int i = 0; i < 6; i++) {
+                b.append((char)(' ' + random.nextInt('~' - ' ' + 1)));
+            }
+            return b.toString();
+        }
+
+        protected static void padBundle(Bundle bundle, int size, int minHash, Random random) {
+            while (bundle.size() < size) {
+                String key;
+                do {
+                    key = randomString(random);
+                } while (key.hashCode() < minHash || bundle.containsKey(key));
+                bundle.putString(key, "PADDING");
+            }
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
index 8903aec..690f661 100644
--- a/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
+++ b/tests/tests/security/src/android/security/cts/ListeningPortsTest.java
@@ -67,6 +67,10 @@
         EXCEPTION_PATTERNS.add(":: 1020");          // used by remote control
         //no current patterns involve address, port and UID combinations
         //Example for when necessary: EXCEPTION_PATTERNS.add("0.0.0.0:5555 10000")
+
+        // IPv6 exceptions
+        // TODO: this is not standard notation for IPv6. Use [$addr]:$port instead as per RFC 3986.
+        EXCEPTION_PATTERNS.add(":::5555");          // emulator port for adb
     }
 
     /**
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 24cfdce..06333a8 100755
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -33,6 +33,8 @@
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
+import android.media.MediaDrm;
+import android.media.MediaDrm.MediaDrmStateException;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
@@ -54,9 +56,13 @@
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.ServerSocket;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.UUID;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -451,11 +457,22 @@
     }
 
     @SecurityTest
+    public void testBug_33298089() throws Exception {
+        int[] frameSizes = {3247, 430, 221, 2305};
+        doStagefrightTestRawBlob(R.raw.bug_33298089_avc, "video/avc", 32, 64, frameSizes);
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2017_0599() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0599);
     }
 
     @SecurityTest
+    public void testStagefright_bug_36492741() throws Exception {
+        doStagefrightTest(R.raw.bug_36492741);
+    }
+
+    @SecurityTest
     public void testStagefright_bug_38487564() throws Exception {
         doStagefrightTest(R.raw.bug_38487564, (4 * 60 * 1000));
     }
@@ -497,6 +514,11 @@
     }
 
     @SecurityTest
+    public void testBug_36993291() throws Exception {
+        doStagefrightTestRawBlob(R.raw.bug_36993291_avc, "video/avc", 320, 240);
+    }
+
+    @SecurityTest
     public void testStagefright_bug_33818508() throws Exception {
         doStagefrightTest(R.raw.bug_33818508);
     }
@@ -525,6 +547,11 @@
     }
 
     @SecurityTest
+    public void testStagefright_bug_69269702() throws Exception {
+        doStagefrightTest(R.raw.bug_69269702);
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2015_3867() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3867);
     }
@@ -625,11 +652,49 @@
     }
 
     @SecurityTest
+    public void testStagefright_bug_37710346() throws Exception {
+        UUID CLEARKEY_SCHEME_UUID = new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL);
+
+        String drmInitString = "0000003470737368" +
+                               "01000000" +
+                               "1077efecc0b24d02" +
+                               "ace33c1e52e2fb4b" +
+                               "10000001" +
+                               "60061e017e477e87" +
+                               "7e57d00d1ed00d1e" +
+                               "00000000";
+        int len = drmInitString.length();
+        byte[] drmInitData = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            drmInitData[i / 2] = (byte) ((Character.digit(drmInitString.charAt(i), 16) << 4) +
+                Character.digit(drmInitString.charAt(i + 1), 16));
+        }
+
+        try {
+            MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+            byte[] sessionId;
+            String initDataType = "video/mp4";
+
+            sessionId = drm.openSession();
+            MediaDrm.KeyRequest drmRequest = drm.getKeyRequest(sessionId, drmInitData,
+                initDataType, MediaDrm.KEY_TYPE_STREAMING, null);
+        } catch (Exception e) {
+            if (!(e instanceof MediaDrmStateException))
+                fail("media drm server died");
+        }
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2015_3873_b_23248776() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3873_b_23248776);
     }
 
     @SecurityTest
+    public void testStagefright_bug_35472997() throws Exception {
+        doStagefrightTest(R.raw.bug_35472997);
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2015_3873_b_20718524() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3873_b_20718524);
     }
@@ -729,6 +794,86 @@
      ***********************************************************/
 
     @SecurityTest
+    public void testStagefright_cve_2017_13279() throws Exception {
+      Thread server = new Thread() {
+        @Override
+        public void run(){
+          try (ServerSocket serverSocket = new ServerSocket(8080);
+            Socket conn = serverSocket.accept()){
+              OutputStream stream = conn.getOutputStream();
+              byte http[] = ("HTTP/1.0 200 OK\r\nContent-Type: application/x-mpegURL\r\n\r\n"
+                           + "#EXTM3U\n#EXT-X-STREAM-INF:\n").getBytes();
+              stream.write(http);
+              while(!conn.isClosed())
+                stream.write(("a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\n").getBytes());
+            }
+          catch(IOException e){
+          }
+        }
+      };
+      server.start();
+      String uri = "http://127.0.0.1:8080/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/"
+                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.m3u8";
+      final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener();
+
+      LooperThread t = new LooperThread(new Runnable() {
+          @Override
+          public void run() {
+
+              MediaPlayer mp = new MediaPlayer();
+              mp.setOnErrorListener(mpcl);
+              mp.setOnPreparedListener(mpcl);
+              mp.setOnCompletionListener(mpcl);
+              Surface surface = getDummySurface();
+              mp.setSurface(surface);
+              AssetFileDescriptor fd = null;
+              try {
+                mp.setDataSource(uri);
+                mp.prepareAsync();
+              } catch (IOException e) {
+                Log.e(TAG, e.toString());
+              } finally {
+                  closeQuietly(fd);
+              }
+
+              Looper.loop();
+              mp.release();
+          }
+      });
+      t.start();
+      Thread.sleep(60000); // Poc takes a while to crash mediaserver, waitForError
+                           // doesn't wait long enough
+      assertFalse("Device *IS* vulnerable to CVE-2017-13279",
+                  mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+      t.stopLooper();
+      t.join(); // wait for thread to exit so we're sure the player was released
+      server.join();
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2017_13276() throws Exception {
         doStagefrightTest(R.raw.cve_2017_13276);
     }
@@ -769,7 +914,10 @@
 
         Bitmap bitmap = BitmapFactory.decodeResource(
                 getInstrumentation().getContext().getResources(), R.raw.bug_73172046);
-        bitmap.recycle();
+        // OK if the decoding failed, but shouldn't cause crashes
+        if (bitmap != null) {
+            bitmap.recycle();
+        }
     }
 
     @SecurityTest
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerClientApiTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerClientApiTest.java
index 56969bb..904f0cf 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerClientApiTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerClientApiTest.java
@@ -32,6 +32,8 @@
 import android.net.Uri;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
 import junit.framework.AssertionFailedError;
 
 /**
@@ -39,6 +41,7 @@
  *
  * In this test, we tests the main functionalities of those, without throttling.
  */
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerClientApiTest extends ShortcutManagerCtsTestsBase {
 
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
index f27a60a..67d99fe 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
@@ -29,6 +29,8 @@
 import android.graphics.drawable.Icon;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
 @SmallTest
 public class ShortcutManagerLauncherApiTest extends ShortcutManagerCtsTestsBase {
     @Override
@@ -350,7 +352,7 @@
         assertIconDimensions(icon5, getIconAsLauncher(
                 mLauncherContext1, mPackageContext1.getPackageName(), "ms21", false));
     }
-
+    @CddTest(requirement="3.8.1/C-1-2")
     public void testGetShortcutIconAdaptive() throws Exception {
         final Icon icon1 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
             getTestContext().getResources(), R.drawable.black_16x64));
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherCallbackTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherCallbackTest.java
index 166c9ba..8467f9a 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherCallbackTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherCallbackTest.java
@@ -38,6 +38,9 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Predicate;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-2-3")
 @SmallTest
 public class ShortcutManagerLauncherCallbackTest extends ShortcutManagerCtsTestsBase {
 
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMaxCountTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMaxCountTest.java
index 8b7ae4e..8b18931 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMaxCountTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMaxCountTest.java
@@ -23,6 +23,9 @@
 
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerMaxCountTest extends ShortcutManagerCtsTestsBase {
     /**
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMiscTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMiscTest.java
index 95defb8..46c8661 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMiscTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMiscTest.java
@@ -20,6 +20,9 @@
 import android.content.pm.ShortcutManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerMiscTest extends ShortcutManagerCtsTestsBase {
     @Override
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMultiLauncherTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMultiLauncherTest.java
index 5ed5d52..5f49e1f 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMultiLauncherTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerMultiLauncherTest.java
@@ -28,6 +28,9 @@
 
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-2-3")
 @SmallTest
 public class ShortcutManagerMultiLauncherTest extends ShortcutManagerCtsTestsBase {
     /**
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
index bae8b0f..c4e492e 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
@@ -33,6 +33,9 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerNegativeTest extends ShortcutManagerCtsTestsBase {
     private static final String TAG = "ShortcutNegativeCTS";
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerRequestPinTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerRequestPinTest.java
index c04c0af..d7b506a 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerRequestPinTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerRequestPinTest.java
@@ -33,15 +33,18 @@
 import android.content.pm.cts.shortcutmanager.common.ReplyUtil;
 import android.os.PersistableBundle;
 import android.util.Log;
+import com.android.compatibility.common.util.CddTest;
 
 import java.util.HashMap;
 import java.util.List;
 
+@CddTest(requirement="3.8.1/C-4-1")
 public class ShortcutManagerRequestPinTest extends ShortcutManagerCtsTestsBase {
     private static final String TAG = "ShortcutMRPT";
 
     private static final String SHORTCUT_ID = "s12345";
 
+    @CddTest(requirement="[3.8.1/C-2-1],[3.8.1/C-3-1]")
     public void testIsRequestPinShortcutSupported() {
 
         // Launcher 1 supports it.
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
index a66e8ed..cdb14d1 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerStartShortcutTest.java
@@ -30,6 +30,9 @@
 
 import java.util.List;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-2-3")
 @SmallTest
 public class ShortcutManagerStartShortcutTest extends ShortcutManagerCtsTestsBase {
     private ComponentName mLaunchedActivity;
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
index 55afe48..7628c82 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
@@ -33,11 +33,14 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.view.KeyEvent;
 
+import com.android.compatibility.common.util.CddTest;
+
 /**
  * The actual test is implemented in the CtsShortcutManagerThrottlingTest module.
  * This class uses broadcast receivers to communicate with it, because if we just used an
  * instrumentation test, the target process would never been throttled.
  */
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerThrottlingTest extends ShortcutManagerCtsTestsBase {
 
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
index 50ce615..a8afaaf 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerUsageTest.java
@@ -27,6 +27,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.format.Time;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="3.8.1/C-4-1")
 @SmallTest
 public class ShortcutManagerUsageTest extends ShortcutManagerCtsTestsBase {
     private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} " +
diff --git a/tests/tests/slice/AndroidTest.xml b/tests/tests/slice/AndroidTest.xml
index ceae60a..34fdb6f 100644
--- a/tests/tests/slice/AndroidTest.xml
+++ b/tests/tests/slice/AndroidTest.xml
@@ -28,4 +28,8 @@
         <option name="package" value="android.slice.cts" />
         <option name="runtime-hint" value="1m" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
index 7a1a826..32dd235 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
@@ -52,6 +52,12 @@
 
     private static final int WAIT_TIME = 2000;
 
+    /**
+     * Color may be slightly off-spec when resources are resized for lower densities. Use this error
+     * margin to accommodate for that when comparing colors.
+     */
+    private static final int COLOR_COMPONENT_ERROR_MARGIN = 10;
+
     private final String NOTIFICATION_TAG = "TEST_TAG";
     private final String NOTIFICATION_CHANNEL_ID = "test_channel";
     private final String NOTIFICATION_GROUP_KEY = "test_group";
@@ -147,7 +153,7 @@
                     (float) s.backgroundPixels / s.totalPixels(),
                     "Is the bar background showing correctly (solid red)?");
 
-            assertMoreThan("Not enough pixels colored as in the spec", 0.1f,
+            assertMoreThan("Not enough pixels colored as in the spec", 0.3f,
                     (float) s.iconPixels / s.foregroundPixels(),
                     "Are the bar icons colored according to the spec "
                             + "(60% black and 24% black)?");
@@ -237,7 +243,7 @@
             }
 
             // What we expect the icons to be colored according to the spec.
-            if (c == mixedIconColor || c == mixedIconPartialColor) {
+            if (isColorSame(c, mixedIconColor) || isColorSame(c, mixedIconPartialColor)) {
                 s.iconPixels++;
                 continue;
             }
@@ -277,4 +283,15 @@
                     fgGreen + (255 - fgAlpha) * bgGreen / 255,
                     fgBlue + (255 - fgAlpha) * bgBlue / 255);
     }
+
+    /**
+     * Check if two colors' diff is in the error margin as defined in
+     * {@link #COLOR_COMPONENT_ERROR_MARGIN}.
+     */
+    private boolean isColorSame(int c1, int c2){
+        return Math.abs(Color.alpha(c1) - Color.alpha(c2)) < COLOR_COMPONENT_ERROR_MARGIN
+                && Math.abs(Color.red(c1) - Color.red(c2)) < COLOR_COMPONENT_ERROR_MARGIN
+                && Math.abs(Color.green(c1) - Color.green(c2)) < COLOR_COMPONENT_ERROR_MARGIN
+                && Math.abs(Color.blue(c1) - Color.blue(c2)) < COLOR_COMPONENT_ERROR_MARGIN;
+    }
 }
diff --git a/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttf b/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttf
index fd49e76..4487483 100644
--- a/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttf
+++ b/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttf
Binary files differ
diff --git a/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttx b/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttx
index 8464b2f..21d6b4c 100644
--- a/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttx
+++ b/tests/tests/text/assets/fonts/StaticLayoutLineBreakingTestFont.ttx
@@ -136,6 +136,7 @@
   <cmap>
     <tableVersion version="0"/>
     <cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0">
+      <map code="0x000a" name="0em" />  <!-- \n -->
       <map code="0x0020" name="10em" />
       <map code="0x002e" name="10em" />  <!-- . -->
       <map code="0x0043" name="100em" />  <!-- C -->
diff --git a/tests/tests/uiautomation/Android.mk b/tests/tests/uiautomation/Android.mk
index 347c55f..b9bdbfb 100644
--- a/tests/tests/uiautomation/Android.mk
+++ b/tests/tests/uiautomation/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ub-uiautomator
 
diff --git a/tests/tests/uirendering/res/layout/circle_clipped_webview.xml b/tests/tests/uirendering/res/layout/circle_clipped_webview.xml
index 44b65be..49add88 100644
--- a/tests/tests/uirendering/res/layout/circle_clipped_webview.xml
+++ b/tests/tests/uirendering/res/layout/circle_clipped_webview.xml
@@ -14,6 +14,7 @@
        limitations under the License.
   -->
 <android.uirendering.cts.testclasses.view.CircleClipFrameLayout
+    android:id="@+id/circle_clip_frame_layout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/test_width"
     android:layout_height="@dimen/test_height">
diff --git a/tests/tests/uirendering/res/layout/frame_layout_webview.xml b/tests/tests/uirendering/res/layout/frame_layout_webview.xml
new file mode 100644
index 0000000..a3afd81
--- /dev/null
+++ b/tests/tests/uirendering/res/layout/frame_layout_webview.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/frame_layout"
+    android:layout_width="@dimen/test_width"
+    android:layout_height="@dimen/test_height">
+    <include layout="@layout/test_content_webview"/>
+</FrameLayout>
diff --git a/tests/tests/uirendering/res/layout/test_content_webview.xml b/tests/tests/uirendering/res/layout/test_content_webview.xml
index 8b03cab..32762ec 100644
--- a/tests/tests/uirendering/res/layout/test_content_webview.xml
+++ b/tests/tests/uirendering/res/layout/test_content_webview.xml
@@ -14,5 +14,6 @@
   -->
 <WebView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/webview"
     android:layout_width="@dimen/test_width"
     android:layout_height="@dimen/test_height"/>
\ No newline at end of file
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
index 2f8823a..3391bb9 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
@@ -17,6 +17,7 @@
 package android.uirendering.cts.testclasses;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -106,6 +107,7 @@
     public void testReadbackThroughPicture() {
         Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
                 HARDWARE_OPTIONS);
+        assertEquals(Bitmap.Config.HARDWARE, hardwareBitmap.getConfig());
         Picture picture = new Picture();
         {
             Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
@@ -121,6 +123,27 @@
     }
 
     @Test
+    public void testReadbackThroughPictureNoEndRecording() {
+        // Exact same test as #testReadbackThroughPicture but with an omitted endRecording
+        Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
+                HARDWARE_OPTIONS);
+        assertEquals(Bitmap.Config.HARDWARE, hardwareBitmap.getConfig());
+        Picture picture = new Picture();
+        {
+            Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
+            canvas.drawColor(Color.WHITE);
+            canvas.drawBitmap(hardwareBitmap, 0, 0, null);
+        }
+        // It will be true, but as endRecording hasn't been called yet it's still in the
+        // "false" state from beginRecording()
+        assertFalse(picture.requiresHardwareAcceleration());
+        Bitmap result = Bitmap.createBitmap(picture, picture.getWidth(), picture.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        assertTrue(new GoldenImageVerifier(getActivity(),
+                R.drawable.golden_robot, new MSSIMComparer(0.95)).verify(result));
+    }
+
+    @Test
     public void testCreateScaledBitmapFromPicture() {
         Picture picture = new Picture();
         {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index 4614680..6b5857f 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -19,30 +19,36 @@
 import static org.junit.Assert.assertEquals;
 
 import android.animation.ValueAnimator;
-import android.graphics.Canvas;
+import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import androidx.annotation.ColorInt;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.uirendering.cts.R;
+import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
 import android.uirendering.cts.bitmapverifiers.ColorCountVerifier;
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
+import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.uirendering.cts.testinfrastructure.ViewInitializer;
+import android.uirendering.cts.util.WebViewReadyHelper;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewTreeObserver;
+import android.webkit.WebView;
 import android.widget.FrameLayout;
 
+import androidx.annotation.ColorInt;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -385,4 +391,246 @@
                 })
                 .runWithVerifier(new ColorVerifier(Color.RED));
     }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.test_content_webview, (ViewInitializer) view -> {
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+                    webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                }, true, hwFence)
+                .runWithVerifier(new ColorVerifier(Color.BLUE));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithOffsetLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.frame_layout_webview, (ViewInitializer) view -> {
+                    FrameLayout layout = view.requireViewById(R.id.frame_layout);
+                    layout.setBackgroundColor(Color.RED);
+
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                    webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                    webview.setTranslationX(10);
+                    webview.setTranslationY(10);
+                    webview.getLayoutParams().width = TEST_WIDTH - 20;
+                    webview.getLayoutParams().height = TEST_HEIGHT - 20;
+                }, true, hwFence)
+                .runWithVerifier(new RectVerifier(Color.RED, Color.BLUE,
+                        new Rect(10, 10, TEST_WIDTH - 10, TEST_HEIGHT - 10)));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithParentLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.frame_layout_webview, (ViewInitializer) view -> {
+                    FrameLayout layout = view.requireViewById(R.id.frame_layout);
+                    layout.setBackgroundColor(Color.RED);
+                    layout.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                    webview.setTranslationX(10);
+                    webview.setTranslationY(10);
+                    webview.getLayoutParams().width = TEST_WIDTH - 20;
+                    webview.getLayoutParams().height = TEST_HEIGHT - 20;
+
+                }, true, hwFence)
+                .runWithVerifier(new RectVerifier(Color.RED, Color.BLUE,
+                        new Rect(10, 10, TEST_WIDTH - 10, TEST_HEIGHT - 10)));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewScaledWithParentLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.frame_layout_webview, (ViewInitializer) view -> {
+                    FrameLayout layout = view.requireViewById(R.id.frame_layout);
+                    layout.setBackgroundColor(Color.RED);
+                    layout.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                    webview.setTranslationX(10);
+                    webview.setTranslationY(10);
+                    webview.setScaleX(0.5f);
+                    webview.getLayoutParams().width = 40;
+                    webview.getLayoutParams().height = 40;
+
+                }, true, hwFence)
+                .runWithVerifier(new RectVerifier(Color.RED, Color.BLUE,
+                        new Rect(20, 10, 40, 50)));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithAlpha() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.test_content_webview, (ViewInitializer) view -> {
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                    // reduce alpha by 50%
+                    webview.setAlpha(0.5f);
+
+                }, true, hwFence)
+                .runWithVerifier(new ColorVerifier(Color.rgb(128, 128, 255)));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithAlphaLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.test_content_webview, (ViewInitializer) view -> {
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                    // reduce alpha by 50%
+                    Paint paint = new Paint();
+                    paint.setAlpha(128);
+                    webview.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
+
+                    // reduce alpha by another 50% (ensuring two alphas combine correctly)
+                    webview.setAlpha(0.5f);
+
+                }, true, hwFence)
+                .runWithVerifier(new ColorVerifier(Color.rgb(191, 191, 255)));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithUnclippedLayer() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.test_content_webview, (ViewInitializer) view -> {
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"min-height: 120vh; background-color:blue\">");
+                    webview.setVerticalFadingEdgeEnabled(true);
+                    webview.setVerticalScrollBarEnabled(false);
+                    webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+                }, true, hwFence)
+                .runWithVerifier(new SamplePointVerifier(
+                        new Point[] {
+                                // solid area
+                                new Point(0, 0),
+                                new Point(0, TEST_HEIGHT - 1),
+                                // fade area
+                                new Point(0, TEST_HEIGHT - 10),
+                                new Point(0, TEST_HEIGHT - 5)
+                        },
+                        new int[] {
+                                Color.BLUE,
+                                Color.WHITE,
+                                0xffb3b3ff, // white blended with blue
+                                0xffdbdbff  // white blended with blue
+                        }));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithUnclippedLayerAndComplexClip() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                .addLayout(R.layout.circle_clipped_webview, (ViewInitializer) view -> {
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"min-height: 120vh; background-color:blue\">");
+                    webview.setVerticalFadingEdgeEnabled(true);
+                    webview.setVerticalScrollBarEnabled(false);
+                    webview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+                }, true, hwFence)
+                .runWithVerifier(new SamplePointVerifier(
+                        new Point[] {
+                                // solid white area
+                                new Point(0, 0),
+                                new Point(0, TEST_HEIGHT - 1),
+                                // solid blue area
+                                new Point(TEST_WIDTH / 2 , 5),
+                                // fade area
+                                new Point(TEST_WIDTH / 2, TEST_HEIGHT - 10),
+                                new Point(TEST_WIDTH / 2, TEST_HEIGHT - 5)
+                        },
+                        new int[] {
+                                Color.WHITE,
+                                Color.WHITE,
+                                Color.BLUE,
+                                0xffb3b3ff, // white blended with blue
+                                0xffdbdbff  // white blended with blue
+                        }));
+    }
+
+    @LargeTest
+    @Test
+    public void testWebViewWithLayerAndComplexClip() {
+        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return; // no WebView to run test on
+        }
+        CountDownLatch hwFence = new CountDownLatch(1);
+        createTest()
+                // golden client - draw a simple non-AA circle
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(false);
+                    paint.setColor(Color.BLUE);
+                    canvas.drawOval(0, 0, width, height, paint);
+                }, false)
+                // verify against solid color webview, clipped to its parent oval
+                .addLayout(R.layout.circle_clipped_webview, (ViewInitializer) view -> {
+                    FrameLayout layout = view.requireViewById(R.id.circle_clip_frame_layout);
+                    layout.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+                    WebView webview = view.requireViewById(R.id.webview);
+                    WebViewReadyHelper helper = new WebViewReadyHelper(webview, hwFence);
+                    helper.loadData("<body style=\"background-color:blue\">");
+
+                }, true, hwFence)
+                .runWithComparer(new MSSIMComparer(0.95));
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index 119bb39..52a0a8d 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -64,6 +64,7 @@
 
     private int mEglColorSpace = 0;
     private boolean mIsEGLWideGamut = false;
+    private boolean mEGLExtensionUnsupported = false;
 
     static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
     static final int EGL_OPENGL_ES2_BIT = 4;
@@ -202,6 +203,10 @@
         }
     }
 
+    public boolean initGLExtensionUnsupported() {
+        return mEGLExtensionUnsupported;
+    }
+
     public void initGl() throws Throwable {
         initGl(0, false);
     }
@@ -215,6 +220,7 @@
         }
         mEglColorSpace = eglColorSpace;
         mIsEGLWideGamut = useHalfFloat;
+        mEGLExtensionUnsupported = false;
         runOnGLThread(mDoInitGL);
     }
 
@@ -340,6 +346,32 @@
                         GLUtils.getEGLErrorString(mEgl.eglGetError()));
             }
 
+            // check extensions but still attempt to run the test, if the test fails then we check
+            // mEGLExtensionUnsupported to determine if the failure was expected.
+            String extensions = mEgl.eglQueryString(mEglDisplay, EGL10.EGL_EXTENSIONS);
+            if (mEglColorSpace != 0) {
+                String eglColorSpaceString = null;
+                switch (mEglColorSpace) {
+                    case TextureViewTest.EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
+                        eglColorSpaceString = "EGL_EXT_gl_colorspace_display_p3";
+                        break;
+                    case TextureViewTest.EGL_GL_COLORSPACE_SRGB_KHR:
+                        eglColorSpaceString = "EGL_KHR_gl_colorspace";
+                        break;
+                    case TextureViewTest.EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
+                        eglColorSpaceString = "EGL_EXT_gl_colorspace_scrgb_linear";
+                        break;
+                    default:
+                        throw new RuntimeException("Unknown eglColorSpace: " + mEglColorSpace);
+                }
+                if (!extensions.contains(eglColorSpaceString)) {
+                    mEGLExtensionUnsupported = true;
+                }
+            }
+            if (mIsEGLWideGamut && !extensions.contains("EXT_pixel_format_float")) {
+                mEGLExtensionUnsupported = true;
+            }
+
             mEglConfig = chooseEglConfig();
             if (mEglConfig == null) {
                 throw new RuntimeException("eglConfig not initialized");
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 8a474e7..f3f5318 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -238,8 +238,8 @@
             activity.initGl(eglColorSpace, useHalfFloat);
         } catch (RuntimeException e) {
             // failure to init GL with the right colorspace is not a TextureView failure as some
-            // devices may not support 16-bits
-            if (!useHalfFloat) {
+            // devices may not support 16-bits or the colorspace extension
+            if (!activity.initGLExtensionUnsupported()) {
                 fail("Unable to initGL : " + e);
             }
             return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
index 5f5d78d..db1be3a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
@@ -121,10 +121,25 @@
 
     @Override
     protected void tearDown() throws Exception {
+        // make sure to stop everything and clean up
+        ensureTracingStopped();
+        if (singleThreadExecutor != null) {
+            singleThreadExecutor.shutdown();
+            if (!singleThreadExecutor.awaitTermination(EXECUTOR_TIMEOUT, TimeUnit.SECONDS)) {
+                fail("Failed to shutdown executor");
+            }
+        }
         if (mOnUiThread != null) {
             mOnUiThread.cleanUp();
         }
-        // make sure to stop everything and clean up
+        super.tearDown();
+    }
+
+    private void ensureTracingStopped() throws Exception {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
         TracingController.getInstance().stop(null, singleThreadExecutor);
         Callable<Boolean> tracingStopped = new Callable<Boolean>() {
             @Override
@@ -133,12 +148,6 @@
             }
         };
         PollingCheck.check("Tracing did not stop", POLLING_TIMEOUT, tracingStopped);
-
-        singleThreadExecutor.shutdown();
-        if (!singleThreadExecutor.awaitTermination(EXECUTOR_TIMEOUT, TimeUnit.SECONDS)) {
-            fail("Failed to shutdown executor");
-        }
-        super.tearDown();
     }
 
     private ThreadFactory getCustomThreadFactory() {
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
index 606c86fa..83014b9 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
@@ -265,6 +265,42 @@
         assertEquals(keyProgressIncrement + 1, myAbsSeekBar.getKeyProgressIncrement());
     }
 
+    @Test
+    public void testAccessMin() {
+        AbsSeekBar myAbsSeekBar = new MyAbsSeekBar(mActivity, null, R.style.TestProgressBar);
+
+        int progress = -5;
+        int min = progress - 1;
+        int max = 5;
+        myAbsSeekBar.setMax(max);
+        myAbsSeekBar.setMin(min);
+        myAbsSeekBar.setProgress(progress);
+        assertEquals(min, myAbsSeekBar.getMin());
+        assertEquals(progress, myAbsSeekBar.getProgress());
+        assertEquals(1, myAbsSeekBar.getKeyProgressIncrement());
+
+        min = progress + 1;
+        myAbsSeekBar.setMin(min);
+        assertEquals(min, myAbsSeekBar.getMin());
+        assertEquals(min, myAbsSeekBar.getProgress());
+        assertEquals(1, myAbsSeekBar.getKeyProgressIncrement());
+
+        int keyProgressIncrement = 10;
+        myAbsSeekBar.setKeyProgressIncrement(keyProgressIncrement);
+        assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement());
+        max = (keyProgressIncrement - 1) * 10;
+        min = -1 * keyProgressIncrement * 10;
+        myAbsSeekBar.setMax(max);
+        myAbsSeekBar.setMin(min);
+        assertEquals(keyProgressIncrement, myAbsSeekBar.getKeyProgressIncrement());
+
+        max += 20;
+        myAbsSeekBar.setMax(max);
+        assertEquals(keyProgressIncrement + 1, myAbsSeekBar.getKeyProgressIncrement());
+        assertEquals(min, myAbsSeekBar.getMin());
+        assertEquals(max, myAbsSeekBar.getMax());
+    }
+
     @UiThreadTest
     @Test
     public void testThumbTint() {
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java b/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
index 282ee5f..ffa5a28 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
@@ -61,15 +61,15 @@
     @Parameterized.Parameter(5)
     public boolean differentTypeface;
     @Parameterized.Parameter(6)
-    public boolean differentFontVariationSettings;
-    @Parameterized.Parameter(7)
     public boolean differentElegantTextHeight;
-    @Parameterized.Parameter(8)
+    @Parameterized.Parameter(7)
     public boolean differentBreakStrategy;
-    @Parameterized.Parameter(9)
+    @Parameterized.Parameter(8)
     public boolean differentHyphenationFrequency;
-    @Parameterized.Parameter(10)
+    @Parameterized.Parameter(9)
     public boolean differentTextDir;
+    @Parameterized.Parameter(10)
+    public boolean differentFontVariationSettings;
 
     // text size from the default value.
     private Pair<Params, String[]> makeDifferentParams(Params params) {
@@ -156,8 +156,12 @@
         ArrayList<Object[]> allParams = new ArrayList<>();
 
         // Compute the powerset except for all false case.
-        int allParameterCount = 11;
-        for (int bits = 1; bits < (1 << allParameterCount); ++bits) {
+        final int allParameterCount = 11;
+        // The 11-th bit is for font variation settings. Don't add test case if the system don't
+        // have variable fonts.
+        final int fullBits = hasVarFont()
+                ? (1 << allParameterCount) - 1 : (1 << (allParameterCount - 1)) - 1;
+        for (int bits = 1; bits <= fullBits; ++bits) {
             Object[] param = new Object[allParameterCount];
             for (int j = 0; j < allParameterCount; ++j) {
                 param[j] = new Boolean((bits & (1 << j)) != 0);
@@ -167,6 +171,12 @@
         return allParams;
     }
 
+    private static boolean hasVarFont() {
+        final TextPaint copied = new TextPaint((new TextView(getContext())).getPaint());
+        return copied.setFontVariationSettings("'wght' 400")
+                && copied.setFontVariationSettings("'wdth' 100");
+    }
+
     @SmallTest
     @Test
     public void setText() {
diff --git a/tests/ui/src/android/ui/cts/WatchPercentageScreenDimenTest.java b/tests/ui/src/android/ui/cts/WatchPercentageScreenDimenTest.java
index 4df824c..c550f82 100644
--- a/tests/ui/src/android/ui/cts/WatchPercentageScreenDimenTest.java
+++ b/tests/ui/src/android/ui/cts/WatchPercentageScreenDimenTest.java
@@ -31,9 +31,11 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class WatchPercentageScreenDimenTest {
+
     private Context mContext;
     private Configuration mConfig;
     private float mScreenWidth;
+    private DisplayMetrics mDisplayMetrics;
 
     private boolean isRoundWatch() {
         return mConfig.isScreenRound() && (mConfig.uiMode & Configuration.UI_MODE_TYPE_WATCH)
@@ -44,7 +46,8 @@
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getTargetContext();
         mConfig = mContext.getResources().getConfiguration();
-        mScreenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
+        mDisplayMetrics = mContext.getResources().getDisplayMetrics();
+        mScreenWidth = mDisplayMetrics.widthPixels;
     }
 
     @Test
@@ -54,6 +57,7 @@
         }
 
         float expected = mScreenWidth * 0.1f;
+        float expectedDelta = getMaxErrorRatio() * expected;
 
         TypedArray attrs = mContext.obtainStyledAttributes(new int[] {
             android.R.attr.listPreferredItemPaddingEnd
@@ -63,7 +67,7 @@
         for (int i = 0; i < attrs.length(); ++i) {
             float actual = attrs.getDimension(i, -1);
             Assert.assertEquals("screen_percentage_10 is not 10% of screen width",
-                    expected, actual, 0.1f);
+                    expected, actual, expectedDelta + 0.01f);
         }
     }
 
@@ -74,6 +78,7 @@
         }
 
         float expected = mScreenWidth * 0.15f;
+        float expectedDelta = getMaxErrorRatio() * expected;
 
         TypedArray attrs = mContext.obtainStyledAttributes(new int[] {
             android.R.attr.dialogPreferredPadding,
@@ -86,7 +91,14 @@
         for (int i = 0; i < attrs.length(); ++i) {
             float actual = attrs.getDimension(i, -1);
             Assert.assertEquals("screen_percentage_15 is not 15% of screen width",
-                    expected, actual, 0.1f);
+                    expected, actual, expectedDelta + 0.01f);
         }
     }
+
+    private float getMaxErrorRatio() {
+        // The size used will be the closest qualifier with width <= device width, so there may be
+        // small rounding errors.
+        float widthDp = mDisplayMetrics.widthPixels / mDisplayMetrics.density;
+        return (widthDp - (float) Math.floor(widthDp)) / widthDp;
+    }
 }