Merge "Theme tests for Material" into mnc-dev
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index bc77a62..82346ec 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -211,12 +211,20 @@
     set_filter_off_or_fast_if_possible(props, req,
         "android.colorCorrection.availableAberrationModes",
         "android.colorCorrection.aberrationMode")
-    set_filter_off_or_fast_if_possible(props, req,
-        "android.hotPixel.availableHotPixelModes",
-        "android.hotPixel.mode")
-    set_filter_off_or_fast_if_possible(props, req,
-        "android.edge.availableEdgeModes",
-        "android.edge.mode")
+    if props.has_key("android.request.availableCharacteristicsKeys"):
+        hot_pixel_modes = 393217 in props["android.request.availableCharacteristicsKeys"]
+        edge_modes = 196610 in props["android.request.availableCharacteristicsKeys"]
+    if props.has_key("android.request.availableRequestKeys"):
+        hot_pixel_mode = 393216 in props["android.request.availableRequestKeys"]
+        edge_mode = 196608 in props["android.request.availableRequestKeys"]
+    if hot_pixel_modes and hot_pixel_mode:
+        set_filter_off_or_fast_if_possible(props, req,
+            "android.hotPixel.availableHotPixelModes",
+            "android.hotPixel.mode")
+    if edge_modes and edge_mode:
+        set_filter_off_or_fast_if_possible(props, req,
+            "android.edge.availableEdgeModes",
+            "android.edge.mode")
 
 def get_fastest_manual_capture_settings(props):
     """Return a capture request and format spec for the fastest capture.
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index b4ca4cb..375a6af 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -48,16 +48,19 @@
     check('props["android.info.supportedHardwareLevel"] is not None')
     check('props["android.info.supportedHardwareLevel"] in [0,1,2]')
     full = getval('props["android.info.supportedHardwareLevel"]') == 1
+    manual_sensor = its.caps.manual_sensor(props)
 
     # Test: rollingShutterSkew, and frameDuration tags must all be present,
     # and rollingShutterSkew must be greater than zero and smaller than all
     # of the possible frame durations.
-    check('md.has_key("android.sensor.frameDuration")')
-    check('md["android.sensor.frameDuration"] is not None')
+    if manual_sensor:
+        check('md.has_key("android.sensor.frameDuration")')
+        check('md["android.sensor.frameDuration"] is not None')
     check('md.has_key("android.sensor.rollingShutterSkew")')
     check('md["android.sensor.rollingShutterSkew"] is not None')
-    check('md["android.sensor.frameDuration"] > '
-          'md["android.sensor.rollingShutterSkew"] > 0')
+    if manual_sensor:
+        check('md["android.sensor.frameDuration"] > '
+              'md["android.sensor.rollingShutterSkew"] > 0')
 
     # Test: timestampSource must be a valid value.
     check('props.has_key("android.sensor.info.timestampSource")')
diff --git a/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
index 910cda2..73834cb 100644
--- a/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
+++ b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
@@ -192,8 +192,8 @@
 
             # Verify reprocessing HQ(2) is similar to regular HQ(2) relative to
             # OFF(0)
-            assert(numpy.isclose(sharpness_reprocess[reprocess_format][2] /
-                                    sharpness_reprocess[reprocess_format][0],
+            assert(numpy.isclose(sharpnesses_reprocess[reprocess_format][2] /
+                                    sharpnesses_reprocess[reprocess_format][0],
                                  sharpness_regular[2] / sharpness_regular[0],
                                  THRESHOLD_RELATIVE_SHARPNESS_DIFF))
 
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index e2d67a1..c5469a7 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -44,6 +44,7 @@
     <string name="test_results_cleared">Test results cleared.</string>
     <string name="view">View</string>
     <string name="test_results_error">Couldn\'t create test results report.</string>
+    <string name="runtime_permissions_error">Cannot continue. Please grant runtime permissions</string>
     <string name="export">Export</string>
     <string name="no_storage">Cannot save report to external storage, see log for details.</string>
     <string name="report_saved">Report saved to: %s</string>
@@ -2029,7 +2030,7 @@
    <!-- Audio Frequency Line Test -->
     <string name="audio_frequency_line_test">Audio Frequency Line Test</string>
     <string name="audio_frequency_line_info">
-        The system will measure the frequency response of the left and right line outputs, 
+        The system will measure the frequency response of the left and right line outputs,
         by feeding them back thru the microphone conection with the loopback jack.
         This test requires the Loopback Plug. Please connect a Loopback Plug on the headset
         connector, and proceed with the instructions on the screen.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
index 8cfc6df..976ff32 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
@@ -16,8 +16,10 @@
 
 package com.android.cts.verifier;
 
+import android.Manifest;
 import android.app.ListActivity;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Menu;
@@ -32,6 +34,20 @@
 /** Top-level {@link ListActivity} for launching tests and managing results. */
 public class TestListActivity extends AbstractTestListActivity implements View.OnClickListener {
 
+    private static final String [] RUNTIME_PERMISSIONS = {
+        Manifest.permission.ACCESS_FINE_LOCATION,
+        Manifest.permission.BODY_SENSORS,
+        Manifest.permission.READ_EXTERNAL_STORAGE,
+        Manifest.permission.READ_PHONE_STATE,
+        Manifest.permission.CALL_PHONE,
+        Manifest.permission.WRITE_CONTACTS,
+        Manifest.permission.CAMERA,
+        Manifest.permission.WRITE_EXTERNAL_STORAGE,
+        Manifest.permission.RECORD_AUDIO,
+        Manifest.permission.READ_CONTACTS
+    };
+    private static final int CTS_VERIFIER_PERMISSION_REQUEST = 1;
+
     private static final String TAG = TestListActivity.class.getSimpleName();
 
     @Override
@@ -43,6 +59,18 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        for (String runtimePermission : RUNTIME_PERMISSIONS) {
+            Log.v(TAG, "Checking permissions for: " + runtimePermission);
+            if (checkSelfPermission(runtimePermission) != PackageManager.PERMISSION_GRANTED) {
+                requestPermissions(RUNTIME_PERMISSIONS, CTS_VERIFIER_PERMISSION_REQUEST);
+                return;
+            }
+
+        }
+        createContinue();
+    }
+
+    private void createContinue() {
         if (!isTaskRoot()) {
             finish();
         }
@@ -63,6 +91,19 @@
     }
 
     @Override
+    public void onRequestPermissionsResult(
+            int requestCode, String permissions[], int[] grantResults) {
+        if (requestCode == CTS_VERIFIER_PERMISSION_REQUEST) {
+            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                createContinue();
+                return;
+            }
+            Log.v(TAG, "Permission not granted.");
+            Toast.makeText(this, R.string.runtime_permissions_error, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.test_list_menu, menu);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 3037376..27f8c28 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -1484,13 +1484,32 @@
 
                 StringBuilder logMsg = new StringBuilder();
                 logMsg.append(String.format(
-                        "Capt result: AE=%d, AF=%d, AWB=%d, sens=%d, exp=%.1fms, dur=%.1fms, ",
+                        "Capt result: AE=%d, AF=%d, AWB=%d, ",
                         result.get(CaptureResult.CONTROL_AE_STATE),
                         result.get(CaptureResult.CONTROL_AF_STATE),
-                        result.get(CaptureResult.CONTROL_AWB_STATE),
-                        result.get(CaptureResult.SENSOR_SENSITIVITY),
-                        result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue() / 1000000.0f,
-                        result.get(CaptureResult.SENSOR_FRAME_DURATION).intValue() / 1000000.0f));
+                        result.get(CaptureResult.CONTROL_AWB_STATE)));
+                int[] capabilities = mCameraCharacteristics.get(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+                if (capabilities == null) {
+                    throw new ItsException("Failed to get capabilities");
+                }
+                boolean readSensorSettings = false;
+                for (int capability : capabilities) {
+                    if (capability ==
+                            CameraCharacteristics.
+                                    REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS) {
+                        readSensorSettings = true;
+                        break;
+                    }
+                }
+                if (readSensorSettings) {
+                    logMsg.append(String.format(
+                            "sens=%d, exp=%.1fms, dur=%.1fms, ",
+                            result.get(CaptureResult.SENSOR_SENSITIVITY),
+                            result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue() / 1000000.0f,
+                            result.get(CaptureResult.SENSOR_FRAME_DURATION).intValue() /
+                                        1000000.0f));
+                }
                 if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null) {
                     logMsg.append(String.format(
                             "gains=[%.1f, %.1f, %.1f, %.1f], ",
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
index f8f1a9a..6dbf8cc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
@@ -302,8 +302,9 @@
      * It cannot be reused.
      */
     private class TriggerVerifier extends TriggerEventListener {
-        private volatile CountDownLatch mCountDownLatch = new CountDownLatch(1);
+        private volatile CountDownLatch mCountDownLatch;
         private volatile TriggerEventRegistry mEventRegistry;
+        private volatile long mTimestampForTriggeredEvent = 0;
 
         // TODO: refactor out if needed
         private class TriggerEventRegistry {
@@ -329,10 +330,7 @@
         }
 
         public long getTimeStampForTriggerEvent() {
-            if (mEventRegistry != null && mEventRegistry.triggerEvent != null) {
-                return mEventRegistry.triggerEvent.timestamp;
-            }
-            return 0;
+            return mTimestampForTriggeredEvent;
         }
 
         public String verifyEventTriggered() throws Throwable {
@@ -388,9 +386,16 @@
         }
 
         private TriggerEventRegistry awaitForEvent() throws InterruptedException {
+            mCountDownLatch = new CountDownLatch(1);
             mCountDownLatch.await(TRIGGER_MAX_DELAY_SECONDS, TimeUnit.SECONDS);
             TriggerEventRegistry registry = mEventRegistry;
 
+            // Save the last timestamp when the event triggered.
+            if (mEventRegistry != null && mEventRegistry.triggerEvent != null) {
+                mTimestampForTriggeredEvent = mEventRegistry.triggerEvent.timestamp;
+            }
+
+            mEventRegistry = null;
             playSound();
             return registry != null ? registry : new TriggerEventRegistry(null, 0);
         }
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
index 4b5259d..20a92aa 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
@@ -101,6 +101,16 @@
         runDeviceTests(PKG, ".UsePermissionTest", "testInteractiveGrant");
     }
 
+    public void testRuntimeGroupGrantSpecificity() throws Exception {
+        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantSpecificity");
+    }
+
+    public void testRuntimeGroupGrantExpansion() throws Exception {
+        assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK), false, false));
+        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantExpansion");
+    }
+
     public void testCompatDefault() throws Exception {
         assertNull(getDevice().installPackage(mCtsBuild.getTestApp(APK_COMPAT), false, false));
         runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatDefault");
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
index 253d85d..ece4ebe 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
@@ -23,5 +23,16 @@
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.cts.usepermission" />
+
+    <!-- Note that WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE;
+         this is a special case. -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <!-- Deliberately request WRITE_CONTACTS but *not* READ_CONTACTS -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
+    <!-- Request two different permissions within the same group -->
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
index d6e97e0..8d3b976 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
@@ -119,4 +119,78 @@
 
         mActivity.finish();
     }
+
+    public void testRuntimeGroupGrantSpecificity() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
+
+        // Go through normal grant flow
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+
+        // request only one permission from the 'contacts' permission group
+        mActivity.requestPermissions(new String[] {
+                android.Manifest.permission.WRITE_CONTACTS }, 43);
+        mDevice.waitForIdle();
+
+        new UiObject(new UiSelector()
+                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
+        mDevice.waitForIdle();
+
+        MyActivity.Result result = mActivity.getResult();
+        assertEquals(43, result.requestCode);
+        assertEquals(android.Manifest.permission.WRITE_CONTACTS, result.permissions[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+
+        // We should have only the explicitly requested permission from this group
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
+
+        mActivity.finish();
+    }
+
+    public void testRuntimeGroupGrantExpansion() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
+
+        // Go through normal grant flow
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+
+        // request only one permission from the 'SMS' permission group at runtime,
+        // but two from this group are <uses-permission> in the manifest
+        mActivity.requestPermissions(new String[] {
+                android.Manifest.permission.RECEIVE_SMS }, 44);
+        mDevice.waitForIdle();
+
+        new UiObject(new UiSelector()
+                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
+        mDevice.waitForIdle();
+
+        MyActivity.Result result = mActivity.getResult();
+        assertEquals(44, result.requestCode);
+        assertEquals(android.Manifest.permission.RECEIVE_SMS, result.permissions[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+
+        // We should now have been granted both of the permissions from this group
+        // that are mentioned in our manifest
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
+
+        mActivity.finish();
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 3e76fbc..0e7eb43 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -1993,12 +1993,12 @@
     private long[] getExposureTimeTestValues() {
         long[] testValues = new long[DEFAULT_NUM_EXPOSURE_TIME_STEPS + 1];
         long maxExpTime = mStaticInfo.getExposureMaximumOrDefault(DEFAULT_EXP_TIME_NS);
-        long minxExpTime = mStaticInfo.getExposureMinimumOrDefault(DEFAULT_EXP_TIME_NS);
+        long minExpTime = mStaticInfo.getExposureMinimumOrDefault(DEFAULT_EXP_TIME_NS);
 
-        long range = maxExpTime - minxExpTime;
+        long range = maxExpTime - minExpTime;
         double stepSize = range / (double)DEFAULT_NUM_EXPOSURE_TIME_STEPS;
         for (int i = 0; i < testValues.length; i++) {
-            testValues[i] = minxExpTime + (long)(stepSize * i);
+            testValues[i] = maxExpTime - (long)(stepSize * i);
             testValues[i] = mStaticInfo.getExposureClampToRange(testValues[i]);
         }
 
@@ -2047,7 +2047,7 @@
         }
         int[] testValues = new int[numSteps + 1];
         for (int i = 0; i < testValues.length; i++) {
-            testValues[i] = minSensitivity + stepSize * i;
+            testValues[i] = maxSensitivity - stepSize * i;
             testValues[i] = mStaticInfo.getSensitivityClampToRange(testValues[i]);
         }
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index a6cf613..9f85fd8 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -821,13 +821,21 @@
                     getAvailableMinFrameDurationsForFormatChecked(ImageFormat.JPEG);
             for (int i = mOrderedStillSizes.size() - 2; i >= 0; i--) {
                 Size candidateSize = mOrderedStillSizes.get(i);
-                Long jpegFrameDuration = minFrameDurationMap.get(candidateSize);
-                assertTrue("Cannot find minimum frame duration for jpeg size " + candidateSize,
-                        jpegFrameDuration != null);
-                if (candidateSize.getWidth() <= videoSz.getWidth() &&
-                        candidateSize.getHeight() <= videoSz.getHeight() &&
-                        jpegFrameDuration <= videoFrameDuration) {
-                    videoSnapshotSz = candidateSize;
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    // Legacy level doesn't report min frame duration
+                    if (candidateSize.getWidth() <= videoSz.getWidth() &&
+                            candidateSize.getHeight() <= videoSz.getHeight()) {
+                        videoSnapshotSz = candidateSize;
+                    }
+                } else {
+                    Long jpegFrameDuration = minFrameDurationMap.get(candidateSize);
+                    assertTrue("Cannot find minimum frame duration for jpeg size " + candidateSize,
+                            jpegFrameDuration != null);
+                    if (candidateSize.getWidth() <= videoSz.getWidth() &&
+                            candidateSize.getHeight() <= videoSz.getHeight() &&
+                            jpegFrameDuration <= videoFrameDuration) {
+                        videoSnapshotSz = candidateSize;
+                    }
                 }
             }
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
index 34f2d85..8ccc931 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -306,9 +306,6 @@
             {YUV , MAXIMUM, PRIV, PREVIEW, YUV , RECORD},
             {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , MAXIMUM},
             {PRIV, MAXIMUM, YUV , PREVIEW, YUV , MAXIMUM},
-            {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , RECORD , JPEG, RECORD},
-            {YUV , MAXIMUM, PRIV, PREVIEW, YUV , RECORD , JPEG, RECORD},
-            {PRIV, MAXIMUM, YUV , PREVIEW, PRIV, PREVIEW, YUV , MAXIMUM},
             {PRIV, MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
             {YUV , MAXIMUM, PRIV, PREVIEW, YUV , PREVIEW, JPEG, MAXIMUM},
         };
@@ -1218,7 +1215,7 @@
                 MaxStreamSizes.reprocessConfigToString(reprocessConfig)));
 
         final int TIMEOUT_FOR_RESULT_MS = 3000;
-        final int NUM_REPROCESS_CAPTURES = 3;
+        final int NUM_REPROCESS_CAPTURES_PER_CONFIG = 3;
 
         List<SurfaceTexture> privTargets = new ArrayList<>();
         List<ImageReader> jpegTargets = new ArrayList<>();
@@ -1243,64 +1240,75 @@
         }
 
         try {
-            // reprocessConfig[0:1] is input
-            InputConfiguration inputConfig = getInputConfig(
-                    Arrays.copyOfRange(reprocessConfig, 0, 2), maxSizes);
-
-
-            inputReader = ImageReader.newInstance(inputConfig.getWidth(), inputConfig.getHeight(),
-                    inputConfig.getFormat(), NUM_REPROCESS_CAPTURES);
-            inputReader.setOnImageAvailableListener(inputReaderListener, mHandler);
-            outputSurfaces.add(inputReader.getSurface());
-
             // reprocessConfig[2..] are additional outputs
             setupConfigurationTargets(
                     Arrays.copyOfRange(reprocessConfig, 2, reprocessConfig.length),
                     maxSizes, privTargets, jpegTargets, yuvTargets, rawTargets, outputSurfaces,
-                    NUM_REPROCESS_CAPTURES);
+                    NUM_REPROCESS_CAPTURES_PER_CONFIG);
+
+            // reprocessConfig[0:1] is input
+            InputConfiguration inputConfig = getInputConfig(
+                    Arrays.copyOfRange(reprocessConfig, 0, 2), maxSizes);
+
+            // For each config, YUV and JPEG outputs will be tested. (For YUV reprocessing,
+            // the YUV ImageReader for input is also used for output.)
+            final int totalNumReprocessCaptures =  NUM_REPROCESS_CAPTURES_PER_CONFIG * (
+                    (inputConfig.getFormat() == ImageFormat.YUV_420_888 ? 1 : 0) +
+                    jpegTargets.size() + yuvTargets.size());
+
+            // It needs 1 input buffer for each reprocess capture + the number of buffers
+            // that will be used as outputs.
+            inputReader = ImageReader.newInstance(inputConfig.getWidth(), inputConfig.getHeight(),
+                    inputConfig.getFormat(),
+                    totalNumReprocessCaptures + NUM_REPROCESS_CAPTURES_PER_CONFIG);
+            inputReader.setOnImageAvailableListener(inputReaderListener, mHandler);
+            outputSurfaces.add(inputReader.getSurface());
 
             // Verify we can create a reprocessable session with the input and all outputs.
             BlockingSessionCallback sessionListener = new BlockingSessionCallback();
             CameraCaptureSession session = configureReprocessableCameraSession(mCamera,
                     inputConfig, outputSurfaces, sessionListener, mHandler);
             inputWriter = ImageWriter.newInstance(session.getInputSurface(),
-                    NUM_REPROCESS_CAPTURES);
+                    totalNumReprocessCaptures);
 
             // Prepare a request for reprocess input
             CaptureRequest.Builder builder = mCamera.createCaptureRequest(
                     CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
             builder.addTarget(inputReader.getSurface());
 
-            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
+            for (int i = 0; i < totalNumReprocessCaptures; i++) {
                 session.capture(builder.build(), inputCaptureListener, mHandler);
             }
 
             List<CaptureRequest> reprocessRequests = new ArrayList<>();
-            int numReprocessOutputs = 0;
+            List<Surface> reprocessOutputs = new ArrayList<>();
+            if (inputConfig.getFormat() == ImageFormat.YUV_420_888) {
+                reprocessOutputs.add(inputReader.getSurface());
+            }
 
-            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
-                TotalCaptureResult result = inputCaptureListener.getTotalCaptureResult(
-                        TIMEOUT_FOR_RESULT_MS);
-                builder =  mCamera.createReprocessCaptureRequest(result);
-                inputWriter.queueInputImage(inputReaderListener.getImage(TIMEOUT_FOR_RESULT_MS));
+            for (ImageReader reader : jpegTargets) {
+                reprocessOutputs.add(reader.getSurface());
+            }
 
-                // Test mandatory YUV and JPEG reprocess outputs.
-                for (ImageReader reader : jpegTargets) {
-                    builder.addTarget(reader.getSurface());
-                    numReprocessOutputs++;
+            for (ImageReader reader : yuvTargets) {
+                reprocessOutputs.add(reader.getSurface());
+            }
+
+            for (int i = 0; i < NUM_REPROCESS_CAPTURES_PER_CONFIG; i++) {
+                for (Surface output : reprocessOutputs) {
+                    TotalCaptureResult result = inputCaptureListener.getTotalCaptureResult(
+                            TIMEOUT_FOR_RESULT_MS);
+                    builder =  mCamera.createReprocessCaptureRequest(result);
+                    inputWriter.queueInputImage(
+                            inputReaderListener.getImage(TIMEOUT_FOR_RESULT_MS));
+                    builder.addTarget(output);
+                    reprocessRequests.add(builder.build());
                 }
-
-                for (ImageReader reader : yuvTargets) {
-                    builder.addTarget(reader.getSurface());
-                    numReprocessOutputs++;
-                }
-
-                reprocessRequests.add(builder.build());
             }
 
             session.captureBurst(reprocessRequests, reprocessOutputCaptureListener, mHandler);
 
-            for (int i = 0; i < numReprocessOutputs; i++) {
+            for (int i = 0; i < reprocessOutputs.size() * NUM_REPROCESS_CAPTURES_PER_CONFIG; i++) {
                 TotalCaptureResult result = reprocessOutputCaptureListener.getTotalCaptureResult(
                         TIMEOUT_FOR_RESULT_MS);
             }
diff --git a/tests/tests/hardware/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java b/tests/tests/hardware/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
index aa34de3..d1ca19a 100644
--- a/tests/tests/hardware/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
+++ b/tests/tests/hardware/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
@@ -16,6 +16,7 @@
 
 package android.hardware.multiprocess.camera.cts;
 
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
@@ -112,7 +113,8 @@
         super.setUp();
 
         mCompleted = false;
-        mContext = getActivity();
+        getActivity();
+        mContext = getInstrumentation().getTargetContext();
         System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(mContext);
@@ -232,6 +234,7 @@
         assertTrue("Remote camera service exited early", timeoutExceptionHit);
         android.os.Process.killProcess(mProcessPid);
         mProcessPid = -1;
+        forceCtsActivityToTop();
     }
 
     /**
@@ -337,6 +340,19 @@
         assertTrue("Remote camera service exited early", timeoutExceptionHit);
         android.os.Process.killProcess(mProcessPid);
         mProcessPid = -1;
+        forceCtsActivityToTop();
+    }
+
+    /**
+     * Ensure the CTS activity becomes foreground again instead of launcher.
+     */
+    private void forceCtsActivityToTop() throws InterruptedException {
+        Thread.sleep(WAIT_TIME);
+        Activity a = getActivity();
+        Intent activityIntent = new Intent(a, CameraCtsActivity.class);
+        activityIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        a.startActivity(activityIntent);
+        Thread.sleep(WAIT_TIME);
     }
 
     /**
@@ -389,15 +405,15 @@
     public void startRemoteProcess(java.lang.Class<?> klass, String processName)
             throws InterruptedException {
         // Ensure no running activity process with same name
-        String cameraActivityName = mContext.getPackageName() + ":" + processName;
+        Activity a = getActivity();
+        String cameraActivityName = a.getPackageName() + ":" + processName;
         List<ActivityManager.RunningAppProcessInfo> list =
                 mActivityManager.getRunningAppProcesses();
         assertEquals(-1, getPid(cameraActivityName, list));
 
         // Start activity in a new top foreground process
-        Intent activityIntent = new Intent(mContext, klass);
-        activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(activityIntent);
+        Intent activityIntent = new Intent(a, klass);
+        a.startActivity(activityIntent);
         Thread.sleep(WAIT_TIME);
 
         // Fail if activity isn't running
diff --git a/tests/tests/media/res/raw/heap_oob_flac.mp3 b/tests/tests/media/res/raw/heap_oob_flac.mp3
new file mode 100644
index 0000000..ae542d0
--- /dev/null
+++ b/tests/tests/media/res/raw/heap_oob_flac.mp3
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 86f0313..d5b2907 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -95,6 +95,37 @@
         }
     }
 
+    public void testFlacHeapOverflow() throws Exception {
+        testIfMediaServerDied(R.raw.heap_oob_flac);
+    }
+
+    private void testIfMediaServerDied(int res) throws Exception {
+        mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+            @Override
+            public boolean onError(MediaPlayer mp, int what, int extra) {
+                assertTrue(mp == mMediaPlayer);
+                assertTrue("mediaserver process died", what != MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+                return false;
+            }
+        });
+
+        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(MediaPlayer mp) {
+                assertTrue(mp == mMediaPlayer);
+                mOnCompletionCalled.signal();
+            }
+        });
+
+        AssetFileDescriptor afd = mResources.openRawResourceFd(res);
+        mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+        afd.close();
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        mOnCompletionCalled.waitForSignal();
+        mMediaPlayer.release();
+    }
+
     // Bug 13652927
     public void testVorbisCrash() throws Exception {
         MediaPlayer mp = mMediaPlayer;
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 6bef886..2d55fb6 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -30,10 +30,14 @@
 		android_security_cts_NativeCodeTest.cpp \
 		android_security_cts_SELinuxTest.cpp \
 		android_security_cts_MMapExecutableTest.cpp \
-		android_security_cts_AudioPolicyBinderTest.cpp
+		android_security_cts_AudioPolicyBinderTest.cpp \
+		android_security_cts_EncryptionTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libbinder libutils libmedia libselinux libdl
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libbinder libutils libmedia libselinux libdl libcutils libcrypto
+
+LOCAL_C_INCLUDES += ndk/sources/cpufeatures
+LOCAL_STATIC_LIBRARIES := cpufeatures
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 1051a82..c60b866 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -25,6 +25,7 @@
 extern int register_android_security_cts_SELinuxTest(JNIEnv*);
 extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
 extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
+extern int register_android_security_cts_EncryptionTest(JNIEnv* env);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
@@ -65,5 +66,9 @@
         return JNI_ERR;
     }
 
+    if (register_android_security_cts_EncryptionTest(env)) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_4;
 }
diff --git a/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp b/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp
new file mode 100644
index 0000000..b9e390e
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cpu-features.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <openssl/aes.h>
+#include <openssl/cpu.h>
+#include <openssl/evp.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <new>
+
+#define TEST_EVP_CIPHER     EVP_aes_256_cbc()
+#define TEST_BUFSIZE        (1 * 1024 * 1024) /* 1 MiB */
+#define TEST_ITERATIONS     100 /* MiB */
+#define TEST_THRESHOLD      2000 /* ms */
+
+/*
+ * Function: deviceIsEncrypted
+ * Purpose: Check the device is encrypted
+ * Parameters: none
+ * Returns: boolean: (true) if encrypted, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_deviceIsEncrypted(JNIEnv *, jobject)
+{
+    char prop_value[PROP_VALUE_MAX];
+    property_get("ro.crypto.state", prop_value, "");
+
+    jboolean rc = !strcmp(prop_value, "encrypted");
+    ALOGE("EncryptionTest::deviceIsEncrypted: %d", rc);
+
+    return rc;
+}
+
+/*
+ * Function: cpuHasAes
+ * Purpose: Check if we have an ARM CPU with AES instruction
+ * Parameters: none
+ * Returns: boolean: (true) if AES is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_cpuHasAes(JNIEnv *, jobject)
+{
+    jboolean rc = false;
+    AndroidCpuFamily family = android_getCpuFamily();
+    uint64_t features = android_getCpuFeatures();
+
+    if (family == ANDROID_CPU_FAMILY_ARM) {
+        rc = (features & ANDROID_CPU_ARM_FEATURE_AES) != 0;
+    } else if (family == ANDROID_CPU_FAMILY_ARM64) {
+        rc = (features & ANDROID_CPU_ARM64_FEATURE_AES) != 0;
+    }
+
+    ALOGE("EncryptionTest::cpuHasAes: %d", rc);
+    return rc;
+}
+
+/*
+ * Function: cpuHasNeon
+ * Purpose: Check if we have an ARM CPU with NEON instructions
+ * Parameters: none
+ * Returns: boolean: (true) if NEON is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_cpuHasNeon(JNIEnv *, jobject)
+{
+    jboolean rc = false;
+    AndroidCpuFamily family = android_getCpuFamily();
+
+    if (family == ANDROID_CPU_FAMILY_ARM) {
+        rc = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
+    } else {
+        rc = (family == ANDROID_CPU_FAMILY_ARM64);
+    }
+
+    ALOGE("EncryptionTest::cpuHasNeon: %d", rc);
+    return rc;
+}
+
+/*
+ * Function: neonIsEnabled
+ * Purpose: Check if libcrypto is compiled with NEON support
+ * Parameters: none
+ * Returns: boolean: (true) if NEON is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_neonIsEnabled(JNIEnv *, jobject)
+{
+#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+    jboolean rc = CRYPTO_is_NEON_capable();
+#else
+    jboolean rc = false;
+#endif
+
+    ALOGE("EncryptionTest::neonIsEnabled: %d", rc);
+    return rc;
+}
+
+static inline uint64_t ns()
+{
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    return (uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+/*
+ * Function: aesIsFast
+ * Purpose: Test if AES performance is sufficient to require encryption
+ * Parameters: none
+ * Returns: boolean: (true) if AES performance is acceptable, (false) otherwise
+ * Exceptions: InvalidKeyException if EVP_DecryptInit fails, OutOfMemoryError
+ *             if memory allocation fails.
+ */
+static jboolean android_security_cts_EncryptionTest_aesIsFast(JNIEnv *env, jobject)
+{
+    EVP_CIPHER_CTX ctx;
+    uint8_t *buf;
+    uint8_t key[EVP_CIPHER_key_length(TEST_EVP_CIPHER)];
+    uint8_t iv[EVP_CIPHER_iv_length(TEST_EVP_CIPHER)];
+
+    memset(key, 0x42, sizeof(key));
+    memset(iv,  0x11, sizeof(iv));
+
+    EVP_CIPHER_CTX_init(&ctx);
+
+    if (!EVP_DecryptInit(&ctx, TEST_EVP_CIPHER, key, iv)) {
+        jniThrowException(env, "java/security/InvalidKeyException",
+            "EVP_DecryptInit failed");
+        return false;
+    }
+
+    buf = new (std::nothrow) uint8_t[TEST_BUFSIZE +
+                EVP_CIPHER_block_size(TEST_EVP_CIPHER)];
+
+    if (!buf) {
+        jniThrowException(env, "java/lang/OutOfMemoryError",
+            "Failed to allocate test buffer");
+        return false;
+    }
+
+    memset(buf, 0xF0, TEST_BUFSIZE);
+
+    int len;
+    uint64_t t = ns();
+
+    for (int i = 0; i < TEST_ITERATIONS; ++i) {
+        EVP_DecryptUpdate(&ctx, buf, &len, buf, TEST_BUFSIZE);
+    }
+
+    t = ns() - t;
+
+    delete[] buf;
+
+    unsigned long ms = (unsigned long)(t / 1000000);
+    double speed =
+        (double)(TEST_ITERATIONS * TEST_BUFSIZE / (1024 * 1024)) * 1000.0 / ms;
+
+    ALOGE("EncryptionTest::aesIsFast: %u iterations in %lu ms (%.01lf MiB/s) "
+        "(threshold %u ms)", TEST_ITERATIONS, ms, speed, TEST_THRESHOLD);
+
+    return ms < TEST_THRESHOLD;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "deviceIsEncrypted", "()Z",
+            (void *) android_security_cts_EncryptionTest_deviceIsEncrypted },
+    { "cpuHasAes", "()Z",
+            (void *) android_security_cts_EncryptionTest_cpuHasAes },
+    { "cpuHasNeon", "()Z",
+            (void *) android_security_cts_EncryptionTest_cpuHasNeon },
+    { "neonIsEnabled", "()Z",
+            (void *) android_security_cts_EncryptionTest_neonIsEnabled },
+    { "aesIsFast", "()Z",
+            (void *) android_security_cts_EncryptionTest_aesIsFast }
+};
+
+int register_android_security_cts_EncryptionTest(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/security/cts/EncryptionTest");
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/EncryptionTest.java b/tests/tests/security/src/android/security/cts/EncryptionTest.java
new file mode 100644
index 0000000..bd9a458
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/EncryptionTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.test.AndroidTestCase;
+import junit.framework.TestCase;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.util.Log;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EncryptionTest extends AndroidTestCase {
+
+    static {
+        System.loadLibrary("ctssecurity_jni");
+    }
+
+    private static final String TAG = "EncryptionTest";
+
+    private static final String crypto = "/proc/crypto";
+
+    private static native boolean deviceIsEncrypted();
+
+    private static native boolean cpuHasAes();
+
+    private static native boolean cpuHasNeon();
+
+    private static native boolean neonIsEnabled();
+
+    private static native boolean aesIsFast();
+
+    private boolean hasKernelCrypto(String driver) throws Exception {
+        BufferedReader br = new BufferedReader(new FileReader(crypto));
+        Pattern p = Pattern.compile("driver\\s*:\\s*" + driver);
+
+        try {
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (p.matcher(line).matches()) {
+                    Log.i(TAG, crypto + " has " + driver + " (" + line + ")");
+                    return true;
+                }
+            }
+       } finally {
+           br.close();
+       }
+
+       return false;
+    }
+
+    private boolean hasLowRAM() {
+        ActivityManager activityManager =
+            (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
+
+        return activityManager.isLowRamDevice();
+    }
+
+    public void testConfig() throws Exception {
+        if (cpuHasAes()) {
+            // If CPU has AES CE, it must be enabled in kernel
+            assertTrue(crypto + " is missing xts-aes-ce",
+                hasKernelCrypto("xts-aes-ce"));
+        } else if (cpuHasNeon()) {
+            // Otherwise, if CPU has NEON, it must be enabled
+            assertTrue(crypto + " is missing xts-aes-neon (or xts-aes-neonbs)",
+                hasKernelCrypto("xts-aes-neon") ||
+                hasKernelCrypto("xts-aes-neonbs") ||
+                hasKernelCrypto("aes-asm")); // Not recommended alone
+        }
+
+        if (cpuHasNeon()) {
+            assertTrue("libcrypto must have NEON", neonIsEnabled());
+        }
+    }
+
+    public void testEncryption() throws Exception {
+        if (deviceIsEncrypted()) {
+            return;
+        }
+
+        // Optional for low RAM devices
+        if (hasLowRAM()) {
+            Log.i(TAG, "hasLowRAM: true");
+            return;
+        }
+
+        // Required if performance is sufficient
+        assertFalse("Device encryption is required", aesIsFast());
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
index 6a2240e..ccbdd56 100644
--- a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
@@ -317,13 +317,8 @@
             //expected
         }
 
-        try {
-            assertEquals(AdapterView.INVALID_POSITION,
-                    mAdapterView.getPositionForView(new ImageView(mActivity)));
-            fail("Should throw NullPointerException");
-        } catch (NullPointerException e) {
-            //expected
-        }
+        assertEquals(AdapterView.INVALID_POSITION,
+                mAdapterView.getPositionForView(new ImageView(mActivity)));
     }
 
     public void testChangeFocusable() {
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index 8fb61bf..4ba1160d 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -50,6 +50,8 @@
     public static final String RESOLUTION = "resolution";
     public static final String VERSION_SDK = "androidPlatformVersion";
     public static final String VERSION_RELEASE = "buildVersion";
+    public static final String VERSION_BASE_OS = "base_os";
+    public static final String VERSION_SECURITY_PATCH = "security_patch";
     public static final String BUILD_ABI = "build_abi";
     public static final String BUILD_ABI2 = "build_abi2";
     public static final String BUILD_ABIS = "build_abis";
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index 5828259..51da850 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -80,6 +80,8 @@
 
         addResult(VERSION_RELEASE, Build.VERSION.RELEASE);
         addResult(VERSION_SDK, Build.VERSION.SDK);
+        addResult(VERSION_BASE_OS, Build.VERSION.BASE_OS);
+        addResult(VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
 
         DisplayMetrics metrics = new DisplayMetrics();
         WindowManager wm = (WindowManager) getContext().getSystemService(