Merge "Revert "Revert "CTS: Tests for DISALLOW_CONFIG_VPN""" into marshmallow-cts-dev
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 34246cc..c40d981 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -53,6 +53,32 @@
 
 include $(BUILD_PACKAGE)
 
+# Build CTS verifier framework as a libary.
+
+include $(CLEAR_VARS)
+
+define java-files-in
+$(sort $(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find -L $(1) -maxdepth 1 -name *.java -and -not -name ".*") \
+ ))
+endef
+
+LOCAL_MODULE := cts-verifier-framework
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v4
+LOCAL_SDK_VERSION := current
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_SRC_FILES := \
+    $(call java-files-in, src/com/android/cts/verifier) \
+    $(call java-files-in, src/com/android/cts/verifier/backup) \
+    $(call all-java-files-under, src/android) \
+    $(call all-Iaidl-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
+                               compatibility-common-util-devicesidelib_v2 \
+                               compatibility-device-util_v2 \
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # opencv library
 include $(CLEAR_VARS)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b7c54cd..a93334e 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -17,7 +17,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
-      android:versionCode="5">
+      android:versionCode="5"
+      android:versionName="6.0_r2">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23"/>
 
@@ -1443,6 +1444,7 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.TEST_NFC_BEAM" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_CROSS_PROFILE_INTENTS_DIALOG" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
diff --git a/apps/CtsVerifier/res/layout/js_idle.xml b/apps/CtsVerifier/res/layout/js_idle.xml
index 4277173..5289b98 100644
--- a/apps/CtsVerifier/res/layout/js_idle.xml
+++ b/apps/CtsVerifier/res/layout/js_idle.xml
@@ -15,13 +15,6 @@
                 android:layout_height="wrap_content"
                 android:text="@string/js_test_description"
                 android:layout_margin="@dimen/js_padding"/>
-            <TextView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/js_idle_description_1"
-                android:layout_margin="@dimen/js_padding"
-                android:textStyle="bold"/>
-
             <Button
                 android:id="@+id/js_idle_start_test_button"
                 android:layout_width="wrap_content"
@@ -30,6 +23,14 @@
                 android:text="@string/js_start_test_text"
                 android:onClick="startTest"
                 android:enabled="false"/>
+            <TextView
+                android:id="@+id/js_idle_continue_instruction_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/js_idle_continue_instruction"
+                android:layout_margin="@dimen/js_padding"
+                android:textStyle="bold"
+                android:visibility="gone"/>
 
             <LinearLayout
                 android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index ea45c40..20fa197 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -339,8 +339,7 @@
     <string name="hifi_ultrasound_test_default_false_string">false</string>
     <string name="hifi_ultrasound_test_mic_no_support">
         Device does not support near-ultrasound recording.\n
-        All new phones and tablets MUST support near-ultrasound recording.\n
-        Report FAIL if this is a new device, report PASS if this is an updating device.\n</string>
+        Please report PASS.\n</string>
     <string name="hifi_ultrasound_test_spkr_no_support">
         Device does not support near-ultrasound playback.\n
         If this is your reference device, please use a different reference device.\n</string>
@@ -360,8 +359,7 @@
         If this is your reference device, please use a different reference device.\n</string>
     <string name="hifi_ultrasound_speaker_test_spkr_no_support">
         Device does not support near-ultrasound playback.\n
-        All new phones and tablets MUST support near-ultrasound playback.\n
-        Report FAIL if this is a new device, report PASS if this is an updating device.\n</string>
+        Please report PASS.\n</string>
     <string name="hifi_ultrasound_speaker_test_test_side">
         Please wait for the result on the reference device then report here.</string>
     <string name="hifi_ultrasound_speaker_test_reference_side">
@@ -1686,6 +1684,27 @@
     <string name="provisioning_button_finish">Finish</string>
     <string name="provisioning_cross_profile_chooser">Choose an app to complete action</string>
 
+    <string name="provisioning_byod_no_gps_location_feature">No GPS feature present. Skip test.</string>
+    <string name="provisioning_byod_location_mode_enable">Enable location</string>
+    <string name="provisioning_byod_location_mode_enable_toast_location_change">Location changed</string>
+    <string name="provisioning_byod_location_mode_enable_instruction">
+        This test verifies that the location updates can be enabled for the managed profile apps.\n
+        1. Press the go button to go to the location settings page, set the location switch enabled.\n
+        2. Move your position a little bit, verify that location updates toast comes up.\n
+        Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+
+    <string name="provisioning_byod_location_mode_disable">Disable location</string>
+    <string name="provisioning_byod_location_mode_time_out_toast">Timeout waiting for gps location change</string>
+    <string name="provisioning_byod_location_mode_disable_instruction">
+        This test verifies that the location updates can be disabled for the managed profile apps.\n
+        1. Press the go button to go to the location settings page, set the location switch disabled.\n
+        2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds. 
+        Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+
     <!-- Strings for DeviceOwnerProvisioningTest -->
     <string name="provisioning_device_owner">Device Owner Provisioning</string>
     <string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
@@ -1897,6 +1916,9 @@
     <string name="js_start_test_text">Start test</string>
     <string name="js_idle_instructions">Verify the behaviour of the JobScheduler API for when the device is in idle mode. Simply follow the on-screen instructions.</string>
     <string name="js_idle_description_1">Turn the screen off and then back on in order to begin.</string>
+    <string name="js_idle_continue_instruction">
+        Switch off screen and wait for it to turn on to continue.
+    </string>
     <string name="js_idle_item_idle_off">Idle job does not execute when device is not idle.</string>
     <string name="js_idle_item_idle_on">Idle job does execute when device is forced into idle.</string>
 
@@ -2118,6 +2140,10 @@
     <string name="audio_general_headset_port_exists">Does this device have a headset port?</string>
     <string name="audio_general_headset_no">No</string>
     <string name="audio_general_headset_yes">Yes</string>
+    <string name="audio_general_deficiency_found">WARNING: Some results show potential deficiencies on the system.
+    Please consider addressing them for a future release.</string>
+    <string name="audio_general_test_passed">Test Successful</string>
+    <string name="audio_general_test_failed">Test Failed</string>
 
     <!-- Audio Loopback Latency Test -->
     <string name="audio_loopback_test">Audio Loopback Latency Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
index 91b8d93..7212609 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
@@ -98,11 +98,6 @@
      */
     protected abstract void setupTests(ArrayTestListAdapter adapter);
 
-    // Enable Pass Button when all tests passed.
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     public class DefaultTestCallback implements DialogTestListItem.TestCallback {
         final private DialogTestListItem mTest;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 5a08558..2c3d35d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -262,6 +262,10 @@
 
         @Override
         public ReportLog getReportLog() { return reportLog; }
+
+        public void updatePassButton() {
+            getPassButton().setEnabled(mAdapter.allTestsPassed());
+        }
     }
 
     private static <T extends android.app.Activity & PassFailActivity>
@@ -399,16 +403,14 @@
     private static void setTestResultAndFinish(android.app.Activity activity, String testId,
             String testDetails, ReportLog reportLog, View target) {
         boolean passed;
-        switch (target.getId()) {
-            case R.id.pass_button:
-                passed = true;
-                break;
-            case R.id.fail_button:
-                passed = false;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown id: " + target.getId());
+        if (target.getId() == R.id.pass_button) {
+            passed = true;
+        } else if (target.getId() == R.id.fail_button) {
+            passed = false;
+        } else {
+            throw new IllegalArgumentException("Unknown id: " + target.getId());
         }
+
         setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
index 976ff32..6a96961 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
@@ -19,7 +19,9 @@
 import android.Manifest;
 import android.app.ListActivity;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Menu;
@@ -33,19 +35,6 @@
 
 /** 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();
@@ -59,15 +48,25 @@
     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;
-            }
+        try {
+            PackageInfo packageInfo = getPackageManager().getPackageInfo(
+                  getApplicationInfo().packageName, PackageManager.GET_PERMISSIONS);
 
+            if (packageInfo.requestedPermissions != null) {
+                for (String permission : packageInfo.requestedPermissions) {
+                    Log.v(TAG, "Checking permissions for: " + permission);
+                    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+                        requestPermissions(packageInfo.requestedPermissions,
+                                CTS_VERIFIER_PERMISSION_REQUEST);
+                        return;
+                    }
+                }
+            }
+            createContinue();
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Unable to load package's permissions", e);
+            Toast.makeText(this, R.string.runtime_permissions_error, Toast.LENGTH_SHORT).show();
         }
-        createContinue();
     }
 
     private void createContinue() {
@@ -137,21 +136,16 @@
     }
 
     private boolean handleMenuItemSelected(int id) {
-        switch (id) {
-            case R.id.clear:
-                handleClearItemSelected();
-                return true;
-
-            case R.id.view:
-                handleViewItemSelected();
-                return true;
-
-            case R.id.export:
-                handleExportItemSelected();
-                return true;
-
-            default:
-                return false;
+        if (id == R.id.clear) {
+            handleClearItemSelected();
+        } else if (id == R.id.view) {
+            handleViewItemSelected();
+        } else if (id == R.id.export) {
+            handleExportItemSelected();
+        } else {
+            return false;
         }
+
+        return true;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
index 508fae0..edb3bf0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -22,8 +22,8 @@
 import com.android.compatibility.common.util.ReportLog;
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
-import android.content.Context;
 
+import android.content.Context;
 import android.media.AudioDeviceCallback;
 import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
@@ -31,17 +31,13 @@
 import android.media.AudioTrack;
 import android.media.AudioRecord;
 import android.media.MediaRecorder;
-
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
-
 import android.util.Log;
-
 import android.view.View;
 import android.view.View.OnClickListener;
-
 import android.widget.Button;
 import android.widget.TextView;
 import android.widget.SeekBar;
@@ -391,9 +387,15 @@
         Results resultsRight = new Results("Right");
         computeResultsForVector(mFreqAverage1, resultsRight);
         if (resultsLeft.testAll() && resultsRight.testAll()) {
-            //enable button
-            getPassButton().setEnabled(true);
+            String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+            appendResultsToScreen(strSuccess);
+        } else {
+            String strFailed = getResources().getString(R.string.audio_general_test_failed);
+            appendResultsToScreen(strFailed + "\n");
+            String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+            appendResultsToScreen(strWarning);
         }
+        getPassButton().setEnabled(true); //Everybody passes! (for now...)
     }
 
     private void computeResultsForVector(VectorAverage freqAverage,Results results) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
index f9334b3..ba7b86d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -416,8 +416,15 @@
         computeResultsForVector(mFreqAverageRight, resultsRight, false, bandSpecsArray);
         if (resultsLeft.testAll() && resultsRight.testAll() && resultsBase.testAll()) {
             //enable button
-            getPassButton().setEnabled(true);
+            String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+            appendResultsToScreen(strSuccess);
+        } else {
+            String strFailed = getResources().getString(R.string.audio_general_test_failed);
+            appendResultsToScreen(strFailed + "\n");
+            String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+            appendResultsToScreen(strWarning);
         }
+        getPassButton().setEnabled(true); //Everybody passes! (for now...)
     }
 
     private void computeResultsForVector(VectorAverage freqAverage,Results results, boolean isBase,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
index 75b04eb..98d1365 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
@@ -30,6 +30,8 @@
     public double mEstimatedLatencyMs = 0;
     public double mEstimatedLatencyConfidence = 0.0;
 
+    private double mAmplitudeThreshold = 0.001;  // 0.001 = -60 dB noise
+
     public void init(int blockSize, int samplingRate) {
         mBlockSize = blockSize;
         mSamplingRate = samplingRate;
@@ -40,7 +42,7 @@
         log("Started Auto Correlation for data with " + data.length + " points");
         mSamplingRate = samplingRate;
 
-        downsampleData(data, mDataDownsampled);
+        downsampleData(data, mDataDownsampled, mAmplitudeThreshold);
 
         //correlation vector
         autocorrelation(mDataDownsampled, mDataAutocorrelated);
@@ -95,7 +97,7 @@
         return status;
     }
 
-    private boolean downsampleData(double [] data, double [] dataDownsampled) {
+    private boolean downsampleData(double [] data, double [] dataDownsampled, double threshold) {
 
         boolean status = false;
         // mDataDownsampled = new double[mBlockSize];
@@ -106,6 +108,8 @@
         int N = data.length; //all samples available
         double groupSize =  (double) N / mBlockSize;
 
+        int ignored = 0;
+
         int currentIndex = 0;
         double nextGroup = groupSize;
         for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
@@ -118,9 +122,18 @@
             if (currentIndex>=mBlockSize) {
                 break;
             }
-            dataDownsampled[currentIndex] += Math.abs(data[i]);
+
+            double value =  Math.abs(data[i]);
+            if (value >= threshold) {
+                dataDownsampled[currentIndex] += value;
+            } else {
+                ignored++;
+            }
         }
 
+        log(String.format(" Threshold: %.3f, ignored:%d/%d (%%.2f)", threshold, ignored, N,
+                (double) ignored/(double)N));
+
         status = true;
         return status;
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
index fcd88d1..aaea279 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
@@ -165,13 +165,6 @@
         }
     }
 
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     public static class DeskClockIntentFactory implements IntentFactory {
         @Override
         public Intent[] createIntents(String testId, int buttonText) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
index a8bd993..05c1a2e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
@@ -26,15 +26,17 @@
 import android.content.IntentFilter;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.PowerManager;
 import android.util.Log;
+import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 /**
  *  Idle constraints:
- *      The framework doesn't support turning idle mode off. Use the manual tester to ensure that
- *      the device is not in idle mode (by turning the screen off and then back on) before running
- *      the tests.
+ *      The framework doesn't support turning the screen off. Use the manual tester to
+ *      turn off the screen to run to run tests that require idle mode to be on.
  */
 @TargetApi(21)
 public class IdleConstraintTestActivity extends ConstraintTestActivity {
@@ -57,22 +59,35 @@
      */
     private static final int IDLE_ON_JOB_ID = IdleConstraintTestActivity.class.hashCode() + 1;
 
+    private static final int IDLE_ON_TEST_STATE_NOT_IN_PROGRESS = 0;
+    private static final int IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF = 1;
+
     /**
-     * Listens for idle mode off/on events, namely {@link #ACTION_EXPEDITE_IDLE_MODE} and
-     * {@link Intent#ACTION_SCREEN_ON}.
-     * On ACTION_EXPEDITE_IDLE_MODE, we will disable the {@link #mStartButton}, and on
-     * ACTION_SCREEN_ON we enable it. This is to avoid the start button being clicked when the
-     * device is in idle mode.
+     * mTestState stores the state of the tests. It is used to ensure that we only run
+     * the 'idle on' test if screen is turned off after the user has started tests.
      */
-    private BroadcastReceiver mIdleChangedReceiver = new BroadcastReceiver() {
+    private int mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+    private PowerManager mPowerManager;
+    private TextView mContinueInstructionTextView;
+
+    /**
+     * Listens for screen off event. Starts an async task to force device into
+     * idle mode and run the 'idle on' test.
+     */
+    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
-                mStartButton.setEnabled(true);
-            } else if (ACTION_EXPEDITE_IDLE_MODE.equals(intent.getAction())) {
-                mStartButton.setEnabled(false);
+            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+                if (mTestState == IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF) {
+                    mContinueInstructionTextView.setVisibility(View.GONE);
+                    PowerManager.WakeLock wl = mPowerManager.newWakeLock(
+                        PowerManager.PARTIAL_WAKE_LOCK, TAG);
+                    wl.acquire();
+                    new TestIdleModeTaskIdle().execute(wl);
+                }
             } else {
-                Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_ON");
+                Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_OFF");
             }
         }
     };
@@ -86,47 +101,88 @@
         setPassFailButtonClickListeners();
         setInfoResources(R.string.js_idle_test, R.string.js_idle_instructions, -1);
         mStartButton = (Button) findViewById(R.id.js_idle_start_test_button);
+        mContinueInstructionTextView = (TextView) findViewById(
+            R.id.js_idle_continue_instruction_view);
 
-        // Register receiver for idle off/on events.
+        // Register receiver for screen off event.
         IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        intentFilter.addAction(ACTION_EXPEDITE_IDLE_MODE);
+        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
 
-        registerReceiver(mIdleChangedReceiver, intentFilter);
+        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+        registerReceiver(mScreenOffReceiver, intentFilter);
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // Enable start button only if tests are not in progress.
+        if (mTestState == IDLE_ON_TEST_STATE_NOT_IN_PROGRESS) {
+            mStartButton.setEnabled(true);
+            mContinueInstructionTextView.setVisibility(View.GONE);
+        }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        unregisterReceiver(mIdleChangedReceiver);
+        unregisterReceiver(mScreenOffReceiver);
     }
 
     @Override
     protected void startTestImpl() {
-        new TestIdleModeTask().execute();
+        mStartButton.setEnabled(false);
+        new TestIdleModeTaskNotIdle().execute();
     }
 
-    /** Background task that will run the actual test. */
-    private class TestIdleModeTask extends AsyncTask<Void, Void, Void> {
-
+    /** Background task that will run the 'not idle' test. */
+    private class TestIdleModeTaskNotIdle extends AsyncTask<Void, Void, Void> {
         @Override
         protected Void doInBackground(Void... voids) {
             testIdleConstraintFails_notIdle();
+            return null;
+        }
 
+        @Override
+        protected void onPostExecute(Void result) {
+            mTestState = IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF;
+            mContinueInstructionTextView.setVisibility(View.VISIBLE);
+        }
+    }
 
-            // Send the {@link #ACTION_EXPEDITE_IDLE_MODE} broadcast as an ordered broadcast, this
-            // function will block until all receivers have processed the broadcast.
+    /** Background task that will run the 'idle' test. */
+    private class TestIdleModeTaskIdle extends AsyncTask<PowerManager.WakeLock, Void, Void> {
+
+        private PowerManager.WakeLock mPartialWakeLock;
+
+        @Override
+        protected Void doInBackground(PowerManager.WakeLock... wakeLocks) {
+            mPartialWakeLock = wakeLocks[0];
+
             if (!sendBroadcastAndBlockForResult(new Intent(ACTION_EXPEDITE_IDLE_MODE))) {
-                // Fail the test if the broadcast wasn't processed.
                 runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, false));
+            } else {
+                testIdleConstraintExecutes_onIdle();
             }
-
-            testIdleConstraintExecutes_onIdle();
-
             notifyTestCompleted();
             return null;
         }
 
+        @Override
+        protected void onPostExecute(Void result) {
+            // Reset test state
+            mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+            PowerManager.WakeLock fullWakeLock = mPowerManager.newWakeLock(
+                PowerManager.FULL_WAKE_LOCK
+                | PowerManager.ACQUIRE_CAUSES_WAKEUP
+                | PowerManager.ON_AFTER_RELEASE, TAG);
+            // Turn on screen and release both locks
+            fullWakeLock.acquire();
+            fullWakeLock.release();
+            mPartialWakeLock.release();
+        }
     }
 
     /**
@@ -154,6 +210,10 @@
         runOnUiThread(new IdleTestResultRunner(IDLE_OFF_JOB_ID, testPassed));
     }
 
+    /**
+     * Called after screen is switched off and device is forced into idle mode.
+     * Schedule a job with an idle constraint and verify that it executes.
+     */
     private void testIdleConstraintExecutes_onIdle() {
         mTestEnvironment.setUp();
         mJobScheduler.cancelAll();
@@ -172,6 +232,7 @@
             // We'll just indicate that it failed, not why.
             testPassed = false;
         }
+
         runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, testPassed));
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index b129665..2df6407d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -82,6 +82,8 @@
     private TestListItem mKeyguardDisabledFeaturesTest;
     private DialogTestListItem mDisableNfcBeamTest;
     private TestListItem mAuthenticationBoundKeyTest;
+    private DialogTestListItem mEnableLocationModeTest;
+    private DialogTestListItem mDisableLocationModeTest;
 
     public ByodFlowTestActivity() {
         super(R.layout.provisioning_byod,
@@ -347,6 +349,9 @@
         adapter.add(mKeyguardDisabledFeaturesTest);
         adapter.add(mAuthenticationBoundKeyTest);
 
+        /* If there is an application that handles ACTION_IMAGE_CAPTURE, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
             // Capture image intent can be resolved in primary profile, so test.
             mCrossProfileImageCaptureSupportTest = new DialogTestListItem(this,
@@ -362,6 +367,9 @@
                     .show();
         }
 
+        /* If there is an application that handles ACTION_VIDEO_CAPTURE, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureVideoIntent())) {
             // Capture video intent can be resolved in primary profile, so test.
             mCrossProfileVideoCaptureSupportTest = new DialogTestListItem(this,
@@ -409,7 +417,9 @@
             adapter.add(mDisableNfcBeamTest);
         }
 
-        /* TODO: reinstate when bug b/20131958 is fixed
+        /* If there is an application that handles RECORD_SOUND_ACTION, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureAudioIntent())) {
             // Capture audio intent can be resolved in primary profile, so test.
             mCrossProfileAudioCaptureSupportTest = new DialogTestListItem(this,
@@ -424,7 +434,27 @@
                     R.string.provisioning_byod_no_audio_capture_resolver, Toast.LENGTH_SHORT)
                     .show();
         }
-        */
+
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
+            mEnableLocationModeTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_location_mode_enable,
+                    "BYOD_LocationModeEnableTest",
+                    R.string.provisioning_byod_location_mode_enable_instruction,
+                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
+            mDisableLocationModeTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_location_mode_disable,
+                    "BYOD_LocationModeDisableTest",
+                    R.string.provisioning_byod_location_mode_disable_instruction,
+                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
+
+            adapter.add(mEnableLocationModeTest);
+            adapter.add(mDisableLocationModeTest);
+        } else {
+            // The system does not support GPS feature, so skip test.
+            Toast.makeText(ByodFlowTestActivity.this,
+                    R.string.provisioning_byod_no_gps_location_feature, Toast.LENGTH_SHORT)
+                    .show();
+        }
     }
 
     // Return whether the intent can be resolved in the current profile
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 9ea5061..bfac469 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -25,8 +25,13 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.os.UserManager;
 import android.provider.MediaStore;
 import android.provider.Settings;
@@ -51,7 +56,7 @@
  *
  * Note: We have to use a dummy activity because cross-profile intents only work for activities.
  */
-public class ByodHelperActivity extends Activity implements DialogCallback {
+public class ByodHelperActivity extends Activity implements DialogCallback, Handler.Callback {
     static final String TAG = "ByodHelperActivity";
 
     // Primary -> managed intent: query if the profile owner has been set up.
@@ -97,18 +102,30 @@
     public static final String ACTION_TEST_APP_LINKING_DIALOG =
             "com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG";
 
+    // Primary -> managed intent: request to goto the location settings page and listen to updates.
+    public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+            "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK";
+
     public static final int RESULT_FAILED = RESULT_FIRST_USER;
 
     private static final int REQUEST_INSTALL_PACKAGE = 1;
     private static final int REQUEST_IMAGE_CAPTURE = 2;
     private static final int REQUEST_VIDEO_CAPTURE = 3;
     private static final int REQUEST_AUDIO_CAPTURE = 4;
+    private static final int REQUEST_LOCATION_UPDATE = 5;
 
     private static final String ORIGINAL_SETTINGS_NAME = "original settings";
     private Bundle mOriginalSettings;
 
+    private static final int MSG_TIMEOUT = 1;
+
+    private static final long MSG_TIMEOUT_MILLISEC = 15 * 1000;
+
     private ComponentName mAdminReceiverComponent;
     private DevicePolicyManager mDevicePolicyManager;
+    private LocationManager mLocationManager;
+    private Handler mHandler;
+    private boolean mIsLocationUpdated;
 
     private Uri mImageUri;
     private Uri mVideoUri;
@@ -128,6 +145,9 @@
         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
         mDevicePolicyManager = (DevicePolicyManager) getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+        mHandler = new Handler(this);
+        mIsLocationUpdated = false;
         Intent intent = getIntent();
         String action = intent.getAction();
         Log.d(TAG, "ByodHelperActivity.onCreate: " + action);
@@ -234,6 +254,22 @@
             Intent toSend = new Intent(Intent.ACTION_VIEW);
             toSend.setData(Uri.parse("http://com.android.cts.verifier"));
             sendIntentInsideChooser(toSend);
+        } else if (action.equals(ACTION_SET_LOCATION_AND_CHECK_UPDATES)) {
+            // Grant the locaiton permission to the provile owner on cts-verifier.
+            // The permission state does not have to be reverted at the end since the profile onwer
+            // is going to be deleted when BYOD tests ends.
+            grantLocationPermissionToSelf();
+            Intent locationSettingsIntent = getLocationSettingsIntent();
+            if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
+                startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
+                scheduleTimeout();
+            } else {
+                Log.e(TAG, "BYOD settings could not be resolved in managed profile");
+                finish();
+            }
+            mLocationManager.requestLocationUpdates(
+                    LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+            return;
         }
         // This activity has no UI and is only used to respond to CtsVerifier in the primary side.
         finish();
@@ -289,6 +325,13 @@
                 }
                 break;
             }
+            case REQUEST_LOCATION_UPDATE: {
+                Log.d(TAG, "BYOD exit location settings:OK");
+                mLocationManager.removeUpdates(mLocationListener);
+                mHandler.removeMessages(MSG_TIMEOUT);
+                finish();
+                break;
+            }
             default: {
                 Log.wtf(TAG, "Unknown requestCode " + requestCode + "; data = " + data);
                 break;
@@ -314,6 +357,10 @@
         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
     }
 
+    public static Intent getLocationSettingsIntent() {
+        return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+    }
+
     public static Intent createLockIntent() {
         return new Intent(ACTION_LOCKNOW);
     }
@@ -376,8 +423,49 @@
         startActivity(chooser);
     }
 
+    private void grantLocationPermissionToSelf() {
+        mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
+                android.Manifest.permission.ACCESS_FINE_LOCATION,
+                DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+    }
+
+    private final LocationListener mLocationListener = new LocationListener() {
+        @Override
+        public void onLocationChanged(Location location) {
+            if (mIsLocationUpdated) return;
+            showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
+            mIsLocationUpdated = true;
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) {
+        }
+    };
+
+    private void scheduleTimeout() {
+        mHandler.removeMessages(MSG_TIMEOUT);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT), MSG_TIMEOUT_MILLISEC);
+    }
+
     @Override
     public void onDialogClose() {
         finish();
     }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (msg.what == MSG_TIMEOUT) {
+            if (mIsLocationUpdated) return true;
+            showToast(R.string.provisioning_byod_location_mode_time_out_toast);
+        }
+        return true;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index ed6b5eb..db3c58c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.provider.Settings;
 import android.util.Log;
 
 /**
@@ -75,6 +76,7 @@
             filter.addAction(
                     PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
             filter.addAction(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST);
+            filter.addAction(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
index c7e785c..3c0955d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -81,12 +81,5 @@
 
         setTestListAdapter(adapter);
     }
-
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
 }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 2a411f8..72361c1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -126,13 +126,6 @@
         super.finish();
     }
 
-    /**
-     * Enable Pass Button when all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
         adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_check_device_owner_test,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
index 4a292eb..3babb8f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -126,13 +126,6 @@
         });
     }
 
-    /**
-     * Enable Pass Button when all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
         adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
                 CONFIG_MODIFIABLE_WHEN_UNLOCKED_TEST_ID,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
index 920c9ae..5985be6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
@@ -153,13 +153,6 @@
     }
 
     /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
-    /**
      * Receive the WIFI_P2P_STATE_CHANGED_ACTION action.
      */
     class P2pBroadcastReceiver extends BroadcastReceiver {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
index e6f94af..dd53d33 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
@@ -103,11 +103,4 @@
         adapter.add(TestListItem.newTest(testcase.getTestName(), testcase.getTestId(),
                 intent, null));
     }
-
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
index 9684d97..9370ca8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
@@ -220,10 +220,6 @@
                 i, null));
     }
 
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     /** @returns the appropriate RTSP url, or null in case of failure */
     private String lookupRtspUrl(int itag, String signature) {
         String rtspLookupUri = String.format(RTSP_LOOKUP_URI_TEMPLATE, itag, signature);
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index 7fdefb5..b4c7e63 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -29,6 +29,11 @@
 cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
 
 cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+ifeq ($(cts_runtime_hint),)
+$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := "0"
+else
+$(cts_library_xml): PRIVATE_CTS_RUNTIME_HINT := $(cts_runtime_hint)
+endif
 $(cts_library_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
 $(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
@@ -44,6 +49,7 @@
 						-j $(PRIVATE_JAR_PATH) \
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
+						-x "runtimeHint->$(PRIVATE_CTS_RUNTIME_HINT)" \
 						-e $(CTS_EXPECTATIONS) \
 						-b $(CTS_UNSUPPORTED_ABIS) \
 						-a $(CTS_TARGET_ARCH) \
diff --git a/hostsidetests/devicepolicy/Android.mk b/hostsidetests/devicepolicy/Android.mk
index 6708c3d..dc5e117 100644
--- a/hostsidetests/devicepolicy/Android.mk
+++ b/hostsidetests/devicepolicy/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.adminhostside
 
+cts_runtime_hint := 70
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 # Build the test APKs using their own makefiles
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
old mode 100644
new mode 100755
index 5774b0c..27fd36f
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -47,7 +47,7 @@
 public class KeyManagementTest extends
         ActivityInstrumentationTestCase2<KeyManagementActivity> {
 
-    private static final int KEYCHAIN_TIMEOUT_MS = 8000;
+    private static final int KEYCHAIN_TIMEOUT_MS = 6 * 60 * 1000;
     private DevicePolicyManager mDevicePolicyManager;
 
     public KeyManagementTest() {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 214131f..6dc47e6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -205,13 +205,9 @@
         // Now there's only the browser in the managed profile left
         assertAppLinkResult("testReceivedByBrowserActivityInManaged");
 
-        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "always");
-        changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "ask");
-        // We've set the receiver in the primary user to always: only this one should receive the
-        // intent.
-        assertAppLinkResult("testReceivedByAppLinkActivityInPrimary");
 
         changeVerificationStatus(mUserId, INTENT_RECEIVER_PKG, "always");
+        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "always");
         // We have one always in the primary user and one always in the managed profile: the managed
         // profile one should have precedence.
         assertAppLinkResult("testReceivedByAppLinkActivityInManaged");
diff --git a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
index f9daa3c..8eef86d 100644
--- a/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
+++ b/suite/cts/deviceTests/tvproviderperf/src/com/android/cts/tvproviderperf/TvProviderPerfTest.java
@@ -157,12 +157,12 @@
         // Query a channel
         try (final Cursor cursor = mContentResolver.query(Channels.CONTENT_URI,
                 projection, null, null, null)) {
-            final Uri channelUri = TvContract.buildChannelUri(cursor.getLong(0));
             applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
                 @Override
                 public void run(int i) {
                     assertTrue(cursor.moveToNext());
-                    try (Cursor c = mContentResolver.query(channelUri, null, null, null, null)) {
+                    try (Cursor c = mContentResolver.query(TvContract.buildChannelUri(
+                            cursor.getLong(0)), null, null, null, null)) {
                         while (c.moveToNext()) {
                             // Do nothing. Just iterate all the items.
                         }
@@ -321,12 +321,12 @@
         // Query a program
         try (final Cursor cursor = mContentResolver.query(Programs.CONTENT_URI,
                 projection, null, null, null)) {
-            final Uri programUri = TvContract.buildProgramUri(cursor.getLong(0));
             applyBatchTimes = MeasureTime.measure(QUERY_RUNS, new MeasureRun() {
                 @Override
                 public void run(int i) {
                     assertTrue(cursor.moveToNext());
-                    try (Cursor c = mContentResolver.query(programUri, null, null, null, null)) {
+                    try (Cursor c = mContentResolver.query(TvContract.buildProgramUri(
+                            cursor.getLong(0)), null, null, null, null)) {
                         while (c.moveToNext()) {
                             // Do nothing. Just iterate all the items.
                         }
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 01f64b5..385c055 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -361,5 +361,19 @@
    "android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts"
   ],
   bug: 23192492
+},
+{
+  description: "restricted network is not working",
+  names: [
+    "android.net.cts.ConnectivityManagerTest#testRestrictedNetworks"
+  ],
+  bug: 25651805
+},
+{
+  description: "Read from invalid parcel not working",
+  names: [
+    "android.view.cts.MotionEventTest#testReadFromParcelWithInvalidSampleSize"
+  ],
+  bug: 25652250
 }
 ]
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index c8ef253..639741d 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -71,8 +71,8 @@
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_TV, 48);
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_HIGH, 48);
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_280, 48);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 48);
-            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 64);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 80);
+            expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 80);
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_400, 96);
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_420, 112);
             expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXHIGH, 128);
diff --git a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
index 4c1b1f3..c21bc9c 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
@@ -80,6 +80,10 @@
     }
 
     public void testAssistStructure() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.start3pApp(TEST_CASE_TYPE);
         mTestActivity.startTest(TEST_CASE_TYPE);
         waitForAssistantToBeReady(mReadyLatch);
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 46fb8d9..29b35c5 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -19,6 +19,7 @@
 import android.assist.cts.TestStartActivity;
 import android.assist.common.Utils;
 
+import android.app.ActivityManager;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
@@ -57,6 +58,7 @@
 public class AssistTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
     private static final String TAG = "AssistTestBase";
 
+    protected ActivityManager mActivityManager;
     protected TestStartActivity mTestActivity;
     protected AssistContent mAssistContent;
     protected AssistStructure mAssistStructure;
@@ -123,6 +125,7 @@
         intent.putExtra(Utils.TESTCASE_TYPE, testName);
         setActivityIntent(intent);
         mTestActivity = getActivity();
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
     }
 
     /**
diff --git a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
index 557134b..c6ac3a6 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
@@ -83,6 +83,10 @@
     }
 
     public void testAssistantContentViewDimens() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+          Log.d(TAG, "Not running assist tests on low-RAM device.");
+          return;
+        }
         mTestActivity.startTest(Utils.VERIFY_CONTENT_VIEW);
         waitForAssistantToBeReady(mReadyLatch);
         startSession();
diff --git a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
index 5c8aa19..ea4cd3d 100644
--- a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
+++ b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
@@ -63,6 +63,10 @@
     }
 
     public void testContextAndScreenshotOff() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         // Both settings off
         Log.i(TAG, "DisableContext: Screenshot OFF, Context OFF");
         SystemUtil.runShellCommand(getInstrumentation(),
diff --git a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
index 28b2af2..1154179 100644
--- a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
@@ -66,6 +66,10 @@
     }
 
     public void testAssistContentAndAssistData() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.startTest(TEST_CASE_TYPE);
         waitForAssistantToBeReady(mReadyLatch);
         mTestActivity.start3pApp(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
index 35f95a4..fc7c8fb3 100644
--- a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
@@ -77,6 +77,10 @@
     }
 
     public void testSecureActivity() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.startTest(TEST_CASE_TYPE);
         waitForAssistantToBeReady(mReadyLatch);
         mTestActivity.start3pApp(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
index f6b90b9..621361e 100644
--- a/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
@@ -86,6 +86,10 @@
     }
 
     public void testLayerCausesUnderlyingActivityToLoseFocus() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.startTest(Utils.FOCUS_CHANGE);
         waitForAssistantToBeReady(mReadyLatch);
         mTestActivity.start3pApp(Utils.FOCUS_CHANGE);
diff --git a/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
index bc2ab80..25f36b7 100644
--- a/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
+++ b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
@@ -79,6 +79,10 @@
     }
 
     public void testTextView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.start3pApp(TEST_CASE_TYPE);
         mTestActivity.startTest(TEST_CASE_TYPE);
         waitForAssistantToBeReady(mReadyLatch);
@@ -102,4 +106,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
index c886b74..3ed26d1 100644
--- a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
+++ b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
@@ -98,6 +98,10 @@
     }
 
     public void testLayerDoesNotTriggerLifecycleMethods() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.startTest(Utils.LIFECYCLE);
         waitForAssistantToBeReady(mReadyLatch);
         mTestActivity.start3pApp(Utils.LIFECYCLE);
diff --git a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
index 45082ae..b84e334 100644
--- a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
@@ -70,6 +70,10 @@
     }
 
     public void testRedScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         Log.i(TAG, "Starting screenshot test");
         mTestActivity.startTest(TEST_CASE_TYPE);
         Log.i(TAG, "start waitForAssistantToBeReady()");
@@ -81,6 +85,10 @@
     }
 
     public void testGreenScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         Log.i(TAG, "Starting screenshot test");
         mTestActivity.startTest(TEST_CASE_TYPE);
         Log.i(TAG, "start waitForAssistantToBeReady()");
@@ -92,6 +100,10 @@
     }
 
     public void testBlueScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         Log.i(TAG, "Starting screenshot test");
         mTestActivity.startTest(TEST_CASE_TYPE);
         Log.i(TAG, "start waitForAssistantToBeReady()");
diff --git a/tests/tests/assist/src/android/assist/cts/TextViewTest.java b/tests/tests/assist/src/android/assist/cts/TextViewTest.java
index e4390bc..089993d 100644
--- a/tests/tests/assist/src/android/assist/cts/TextViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/TextViewTest.java
@@ -79,6 +79,10 @@
     }
 
     public void testTextView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         mTestActivity.start3pApp(TEST_CASE_TYPE);
         scrollTestApp(0, 0, true, false);
 
@@ -130,4 +134,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/WebViewTest.java b/tests/tests/assist/src/android/assist/cts/WebViewTest.java
index e367e22..4e05494 100644
--- a/tests/tests/assist/src/android/assist/cts/WebViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/WebViewTest.java
@@ -90,6 +90,10 @@
     }
 
     public void testWebView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
             return;
         }
@@ -118,4 +122,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index 672d3ed..edc9538 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -157,6 +157,7 @@
         registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority);
 
         final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION);
+        broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContextWrapper.sendOrderedBroadcast(broadcastIntent, null);
         new PollingCheck(BROADCAST_TIMEOUT) {
             @Override
@@ -186,8 +187,10 @@
         Bundle bundle = new Bundle();
         bundle.putString(KEY_KEPT, VALUE_KEPT);
         bundle.putString(KEY_REMOVED, VALUE_REMOVED);
-        mContextWrapper.sendOrderedBroadcast(new Intent(ResultReceiver.MOCK_ACTION),
-                null, broadcastReceiver, null, 1, INTIAL_RESULT, bundle);
+        Intent intent = new Intent(ResultReceiver.MOCK_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContextWrapper.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1,
+                INTIAL_RESULT, bundle);
 
         synchronized (mLockObj) {
             try {
@@ -216,13 +219,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertTrue(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
@@ -235,13 +238,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver2.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered.
         broadcastReceiver2.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
     }
@@ -256,13 +259,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertTrue(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
@@ -792,9 +795,9 @@
         waitForCondition(con);
     }
 
-    private void waitForFilteredIntent(ContextWrapper contextWrapper,
-            final FilteredReceiver receiver, final String action) throws InterruptedException {
-        contextWrapper.sendOrderedBroadcast(new Intent(action), null);
+    private void waitForFilteredIntent(ContextWrapper contextWrapper, final String action)
+            throws InterruptedException {
+        contextWrapper.sendBroadcast(new Intent(action), null);
 
         synchronized (mLockObj) {
             mLockObj.wait(BROADCAST_TIMEOUT);
@@ -849,7 +852,6 @@
 
     private class FilteredReceiver extends BroadcastReceiver {
         private boolean mHadReceivedBroadCast1 = false;
-
         private boolean mHadReceivedBroadCast2 = false;
 
         public void onReceive(Context context, Intent intent) {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
index 229185d..0476477 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
@@ -97,7 +97,6 @@
         assertNotNull("Can't connect to camera manager!", mCameraManager);
 
         RenderScriptSingleton.setContext(context);
-        // TODO: call clearContext
     }
 
     @Override
@@ -117,11 +116,7 @@
     @Override
     protected void tearDown() throws Exception {
         MaybeNull.close(mCamera);
-
-        // TODO: Clean up RenderScript context in a static test run finished method.
-        // Or alternatively count the # of test methods that are in this test,
-        // once we reach that count, it's time to call the last tear down
-
+        RenderScriptSingleton.clearContext();
         mHandlerThread.quitSafely();
         mHandler = null;
         super.tearDown();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
index 77a0c8e..67c08fe 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -149,7 +149,8 @@
             assertNotNull("Can't get lens facing info", lensFacing);
             if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
                 assertTrue("System doesn't have front camera feature",
-                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT));
+                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
+                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
             } else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
                 assertTrue("System doesn't have back camera feature",
                         mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
@@ -534,7 +535,7 @@
                     java.util.concurrent.TimeUnit.MILLISECONDS);
             assertTrue(String.format("Received unavailability notice for wrong ID " +
                             "(expected %s, got %s)", id, candidateId),
-                    id == candidateId);
+                    id.equals(candidateId));
             assertTrue("Availability events received unexpectedly",
                     availableEventQueue.size() == 0);
 
@@ -549,7 +550,7 @@
                     java.util.concurrent.TimeUnit.MILLISECONDS);
             assertTrue(String.format("Received availability notice for wrong ID " +
                             "(expected %s, got %s)", id, candidateId),
-                    id == candidateId);
+                    id.equals(candidateId));
             assertTrue("Unavailability events received unexpectedly",
                     unavailableEventQueue.size() == 0);
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
index 0da0ce7..bddbd52 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -75,6 +75,8 @@
 
     @Override
     protected void tearDown() throws Exception {
+        RenderScriptSingleton.clearContext();
+
         super.tearDown();
     }
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index f1115c4..9c783e0 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -41,8 +41,11 @@
 import android.util.Size;
 import android.view.Surface;
 
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import static android.hardware.camera2.cts.CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS;
@@ -275,6 +278,8 @@
      * resolution and format supported.
      */
     public void testAllOutputYUVResolutions() throws Exception {
+        Integer[] sessionStates = {BlockingSessionCallback.SESSION_READY,
+                BlockingSessionCallback.SESSION_CONFIGURE_FAILED};
         for (String id : mCameraIds) {
             try {
                 Log.v(TAG, "Testing all YUV image resolutions for camera " + id);
@@ -309,6 +314,7 @@
                         ", at least one JPEG output is required.", jpegSizes.length == 0);
 
                 Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
+                Size maxPreviewSize = mOrderedPreviewSizes.get(0);
 
                 for (int format : supportedYUVFormats) {
                     Size[] targetCaptureSizes =
@@ -343,6 +349,27 @@
                             outputSurfaces.add(jpegSurface);
                             createSession(outputSurfaces);
 
+                            int state = mCameraSessionListener.getStateWaiter().waitForAnyOfStates(
+                                        Arrays.asList(sessionStates),
+                                        CameraTestUtils.SESSION_CONFIGURE_TIMEOUT_MS);
+
+                            if (state == BlockingSessionCallback.SESSION_CONFIGURE_FAILED) {
+                                if (captureSz.getWidth() > maxPreviewSize.getWidth() ||
+                                        captureSz.getHeight() > maxPreviewSize.getHeight()) {
+                                    Log.v(TAG, "Skip testing {yuv:" + captureSz
+                                            + " ,jpeg:" + maxJpegSize + "} for camera "
+                                            + mCamera.getId() +
+                                            " because full size jpeg + yuv larger than "
+                                            + "max preview size (" + maxPreviewSize
+                                            + ") is not supported");
+                                    continue;
+                                } else {
+                                    fail("Camera " + mCamera.getId() +
+                                            ":session configuration failed for {jpeg: " +
+                                            maxJpegSize + ", yuv: " + captureSz + "}");
+                                }
+                            }
+
                             // Warm up camera preview (mainly to give legacy devices time to do 3A).
                             CaptureRequest.Builder warmupRequest =
                                     mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
index 8e4c8e9..211dd0d 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
@@ -70,7 +70,7 @@
             sCache.close();
             sCache = null;
 
-            sRS.destroy();
+            sRS.releaseAllContexts();
             sRS = null;
             sContext = null;
         }
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
index 4c6362a..328b5cd 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
@@ -114,7 +114,7 @@
                 sensor,
                 false,
                 sensor.getMinDelay(),
-                Integer.MAX_VALUE);
+                Integer.MAX_VALUE /*maxReportLatencyUs*/);
 
         TestSensorOperation op = TestSensorOperation.createOperation(environment,
                 sensor.getFifoReservedEventCount() * 2);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index cffafdc..2bbf053 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -168,8 +168,8 @@
         }
 
         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
-        // orientation sensor is required if the device can physically implement it
-        if (hasCompass && hasAccelerometer) {
+        // Note: orientation sensor is deprecated.
+        if (sensor != null) {
             assertEquals(Sensor.TYPE_ORIENTATION, sensor.getType());
             assertSensorValues(sensor);
         }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
index 76f1594..c64810b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
@@ -28,15 +28,16 @@
     // Number of events to truncate (discard) from the initial events received
     private static final int TRUNCATE_EVENTS_COUNT = 1;
 
-    // Number of event gaps to tolerate is the minimum of 1% of total events received or 10.
-    private static final int EVENT_GAP_TOLERANCE_COUNT = 10;
-    private static final double EVENT_GAP_TOLERANCE_PERCENT = 0.01;
+    // Number of event gaps to tolerate is 2% of total number of events received rounded up to next
+    // integer or 20, whichever is smaller.
+    private static final int EVENT_GAP_THRESHOLD_MAX = 20;
+    private static final double EVENT_GAP_TOLERANCE = 0.02;
 
     private final int mExpectedDelayUs;
 
     private final List<IndexedEventPair> mEventGaps = new LinkedList<IndexedEventPair>();
     private TestSensorEvent mPreviousEvent = null;
-    private int mIndex = 0;
+    private int mEventCount = 0;
 
     /**
      * Construct a {@link EventGapVerification}
@@ -72,14 +73,16 @@
         }
 
         final int count = mEventGaps.size();
-        // Ensure that eventGapTolerance is at least 1.
-        int eventGapTolerance = (int)Math.max(1, Math.min(EVENT_GAP_TOLERANCE_COUNT,
-                    EVENT_GAP_TOLERANCE_PERCENT * mIndex));
-        stats.addValue(PASSED_KEY, count <= eventGapTolerance);
+        // Ensure the threshold is rounded up.
+        double eventGapThreshold =
+                Math.ceil(Math.min(EVENT_GAP_THRESHOLD_MAX, mEventCount * EVENT_GAP_TOLERANCE));
+        boolean pass = count <= eventGapThreshold;
+
+        stats.addValue(PASSED_KEY, pass);
         stats.addValue(SensorStats.EVENT_GAP_COUNT_KEY, count);
         stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, getIndexArray(mEventGaps));
 
-        if (count > eventGapTolerance) {
+        if (!pass) {
             StringBuilder sb = new StringBuilder();
             sb.append(count).append(" events gaps: ");
             for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
@@ -109,16 +112,16 @@
      */
     @Override
     protected void addSensorEventInternal(TestSensorEvent event) {
-        if (mIndex >= TRUNCATE_EVENTS_COUNT) {
+        if (mEventCount >= TRUNCATE_EVENTS_COUNT) {
             if (mPreviousEvent != null) {
                 long deltaNs = event.timestamp - mPreviousEvent.timestamp;
                 long deltaUs = TimeUnit.MICROSECONDS.convert(deltaNs, TimeUnit.NANOSECONDS);
                 if (deltaUs > mExpectedDelayUs * THRESHOLD) {
-                    mEventGaps.add(new IndexedEventPair(mIndex, event, mPreviousEvent));
+                    mEventGaps.add(new IndexedEventPair(mEventCount, event, mPreviousEvent));
                 }
             }
             mPreviousEvent = event;
         }
-        mIndex++;
+        mEventCount++;
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
index 09bbdc8..51811a7 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
@@ -105,7 +105,7 @@
             // Any event that arrives within before 0.5*expectedReportLatency is considered
             // to be in the same batch of events, else it is considered as the beginning of a new
             // batch.
-            if (timestampDiff < 0.5 * mExpectedReportLatencyUs/1000) {
+            if (timestampDiff < mExpectedReportLatencyUs/1000/2) {
                 batchCount++;
             } else {
                 endofbatch = true;
diff --git a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
index 197adc2..66e8093 100644
--- a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
@@ -30,6 +30,7 @@
 import java.security.Key;
 import java.security.KeyStore;
 import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
 import java.security.Provider;
 import java.security.SecureRandom;
 import java.security.Security;
@@ -50,6 +51,8 @@
 
 abstract class BlockCipherTestBase extends AndroidTestCase {
 
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
     private KeyStore mAndroidKeyStore;
     private int mNextKeyId;
 
@@ -121,7 +124,7 @@
 
     public void testGetProvider() throws Exception {
         createCipher();
-        Provider expectedProvider = Security.getProvider("AndroidKeyStoreBCWorkaround");
+        Provider expectedProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertSame(expectedProvider, mCipher.getProvider());
     }
 
@@ -1247,8 +1250,8 @@
     }
 
     protected void createCipher() throws NoSuchAlgorithmException,
-            NoSuchPaddingException  {
-        mCipher = Cipher.getInstance(getTransformation());
+            NoSuchPaddingException, NoSuchProviderException  {
+        mCipher = Cipher.getInstance(getTransformation(), EXPECTED_PROVIDER_NAME);
     }
 
     private String getKeyAlgorithm() {
diff --git a/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..6b6040f
--- /dev/null
+++ b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/CodecState.java b/tests/tests/media/src/android/media/cts/CodecState.java
index 6fdbd86..de0bdf8 100644
--- a/tests/tests/media/src/android/media/cts/CodecState.java
+++ b/tests/tests/media/src/android/media/cts/CodecState.java
@@ -220,8 +220,12 @@
                 mSawInputEOS = true;
                 // FIX-ME: in tunneled mode we currently use input EOS as output EOS indicator
                 // we should stream duration
-                if (mTunneled && !mIsAudio) {
-                    mSawOutputEOS = true;
+                if (mTunneled) {
+                    if (!mIsAudio) {
+                        mSawOutputEOS = true;
+                    } else if (mAudioTrack != null) {
+                        mAudioTrack.stop();
+                    }
                 }
                 return false;
             }
@@ -260,6 +264,10 @@
                     index, 0 /* offset */, 0 /* sampleSize */,
                     0 /* sampleTime */, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
 
+            if (mTunneled && mAudioTrack != null) {
+                mAudioTrack.stop();
+            }
+
             mAvailableInputBufferIndices.removeFirst();
         }
 
@@ -271,7 +279,9 @@
         // b/9250789
         Log.d(TAG, "CodecState::onOutputFormatChanged " + mime);
 
+        mIsAudio = false;
         if (mime.startsWith("audio/")) {
+            mIsAudio = true;
             int sampleRate =
                 mOutputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
 
@@ -315,6 +325,9 @@
 
             mSawOutputEOS = true;
 
+            if (mAudioTrack != null && !mTunneled) {
+                mAudioTrack.stop();
+            }
             return false;
         }
 
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 7c4d1fb..b875719 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -575,7 +575,8 @@
         ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
         ByteBuffer[] decoderInputBuffers = null;
         ByteBuffer[] decoderOutputBuffers = null;
-        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+        MediaCodec.BufferInfo decoderInfo = new MediaCodec.BufferInfo();
+        MediaCodec.BufferInfo encoderInfo = new MediaCodec.BufferInfo();
         MediaFormat decoderOutputFormat = null;
         int generateIndex = 0;
         int checkIndex = 0;
@@ -614,9 +615,11 @@
         boolean inputDone = false;
         boolean encoderDone = false;
         boolean outputDone = false;
+        int encoderStatus = -1;
         while (!outputDone) {
             if (VERBOSE) Log.d(TAG, "loop");
 
+
             // If we're not done submitting frames, generate a new one and submit it.  By
             // doing this on every loop we're working to ensure that the encoder always has
             // work to do.
@@ -662,7 +665,10 @@
             //
             // Once we get EOS from the encoder, we don't need to do this anymore.
             if (!encoderDone) {
-                int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+                MediaCodec.BufferInfo info = encoderInfo;
+                if (encoderStatus < 0) {
+                    encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+                }
                 if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                     // no output available yet
                     if (VERBOSE) Log.d(TAG, "no output from encoder available");
@@ -686,18 +692,7 @@
                     encodedData.position(info.offset);
                     encodedData.limit(info.offset + info.size);
 
-                    encodedSize += info.size;
-                    if (outputStream != null) {
-                        byte[] data = new byte[info.size];
-                        encodedData.get(data);
-                        encodedData.position(info.offset);
-                        try {
-                            outputStream.write(data);
-                        } catch (IOException ioe) {
-                            Log.w(TAG, "failed writing debug data to file");
-                            throw new RuntimeException(ioe);
-                        }
-                    }
+                    boolean releaseBuffer = false;
                     if (!decoderConfigured) {
                         // Codec config info.  Only expected on first packet.  One way to
                         // handle this is to manually stuff the data into the MediaFormat
@@ -719,21 +714,41 @@
                         if (VERBOSE) Log.d(TAG, "decoder configured (" + info.size + " bytes)");
                     }
                     if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
-                        // Get a decoder input buffer, blocking until it's available.
+                        // Get a decoder input buffer
                         assertTrue(decoderConfigured);
-                        int inputBufIndex = decoder.dequeueInputBuffer(-1);
-                        ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
-                        inputBuf.clear();
-                        inputBuf.put(encodedData);
-                        decoder.queueInputBuffer(inputBufIndex, 0, info.size,
-                                info.presentationTimeUs, info.flags);
+                        int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
+                        if (inputBufIndex >= 0) {
+                            ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
+                            inputBuf.clear();
+                            inputBuf.put(encodedData);
+                            decoder.queueInputBuffer(inputBufIndex, 0, info.size,
+                                    info.presentationTimeUs, info.flags);
 
-                        encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
-                        if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
-                                + (encoderDone ? " (EOS)" : ""));
+                            encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+                            if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
+                                    + (encoderDone ? " (EOS)" : ""));
+                            releaseBuffer = true;
+                        }
+                    } else {
+                        releaseBuffer = true;
+                    }
+                    if (releaseBuffer) {
+                        encodedSize += info.size;
+                        if (outputStream != null) {
+                            byte[] data = new byte[info.size];
+                            encodedData.position(info.offset);
+                            encodedData.get(data);
+                            try {
+                                outputStream.write(data);
+                            } catch (IOException ioe) {
+                                Log.w(TAG, "failed writing debug data to file");
+                                throw new RuntimeException(ioe);
+                            }
+                        }
+                        encoder.releaseOutputBuffer(encoderStatus, false);
+                        encoderStatus = -1;
                     }
 
-                    encoder.releaseOutputBuffer(encoderStatus, false);
                 }
             }
 
@@ -744,6 +759,7 @@
             // If we're decoding to a Surface, we'll get notified here as usual but the
             // ByteBuffer references will be null.  The data is sent to Surface instead.
             if (decoderConfigured) {
+                MediaCodec.BufferInfo info = decoderInfo;
                 int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                 if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                     // no output available yet
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
index 2473078..f5856ed 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
@@ -54,7 +54,7 @@
 
     private boolean mEncryptedAudio;
     private boolean mEncryptedVideo;
-    private boolean mThreadStarted = false;
+    private volatile boolean mThreadStarted = false;
     private byte[] mSessionId;
     private CodecState mAudioTrackState;
     private int mMediaFormatHeight;
@@ -304,7 +304,7 @@
         CodecState state;
         if (isVideo) {
             state = new CodecState((MediaTimeProvider)this, mVideoExtractor,
-                            trackIndex, format, codec, true, false, 
+                            trackIndex, format, codec, true, false,
                             AudioManager.AUDIO_SESSION_ID_GENERATE);
             mVideoCodecStates.put(Integer.valueOf(trackIndex), state);
         } else {
diff --git a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
index 3847252..4a4e807 100644
--- a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
+++ b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
@@ -43,6 +43,7 @@
     private int mSampleRate;
     private int mNumBytesQueued = 0;
     private LinkedList<QueueElement> mQueue = new LinkedList<QueueElement>();
+    private boolean mStopped;
 
     public NonBlockingAudioTrack(int sampleRate, int channelCount, boolean hwAvSync,
                     int audioSessionId) {
@@ -107,14 +108,17 @@
     }
 
     public void play() {
+        mStopped = false;
         mAudioTrack.play();
     }
 
     public void stop() {
-        mAudioTrack.stop();
-
-        mQueue.clear();
-        mNumBytesQueued = 0;
+        if (mQueue.isEmpty()) {
+            mAudioTrack.stop();
+            mNumBytesQueued = 0;
+        } else {
+            mStopped = true;
+        }
     }
 
     public void pause() {
@@ -128,6 +132,7 @@
         mAudioTrack.flush();
         mQueue.clear();
         mNumBytesQueued = 0;
+        mStopped = false;
     }
 
     public void release() {
@@ -135,6 +140,7 @@
         mNumBytesQueued = 0;
         mAudioTrack.release();
         mAudioTrack = null;
+        mStopped = false;
     }
 
     public void process() {
@@ -153,6 +159,11 @@
             }
             mQueue.removeFirst();
         }
+        if (mStopped) {
+            mAudioTrack.stop();
+            mNumBytesQueued = 0;
+            mStopped = false;
+        }
     }
 
     public int getPlayState() {
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index f5680f6..8797b9b 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -61,6 +61,7 @@
     private MediaFormat mDecOutputFormat;
     private double[] mMeasuredFps;
     private String[] mResultRawData;
+    private boolean mVerifyResults;
 
     private Resources mResources;
     private DeviceReportLog mReportLog;
@@ -68,6 +69,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mVerifyResults = true;
         mResources = mContext.getResources();
         mReportLog = new DeviceReportLog();
     }
@@ -298,6 +300,10 @@
             mResultRawData[round] = result;
         }
 
+        if (!mVerifyResults) {
+            return true;
+        }
+
         return MediaUtils.verifyResults(name, mime, w, h, fps);
     }
 
@@ -541,6 +547,20 @@
                352, 288, true /* isGoog */);
     }
 
+    public void testMPEG40176x0144Other() throws Exception {
+        mVerifyResults = false;
+        decode(VIDEO_MPEG4,
+               R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+               176, 144, false /* isGoog */);
+    }
+
+    public void testMPEG40176x0144Goog() throws Exception {
+        mVerifyResults = false;
+        decode(VIDEO_MPEG4,
+               R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+               176, 144, true /* isGoog */);
+    }
+
     public void testMPEG40480x0360Other() throws Exception {
         decode(VIDEO_MPEG4,
                R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 152789c..4478bd4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -21,6 +21,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
 import android.net.NetworkInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
@@ -29,6 +31,7 @@
 import android.net.wifi.WifiManager.TxPacketCountListener;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -278,6 +281,14 @@
             Log.d(TAG, "Skipping test as WiFi is not supported");
             return;
         }
+        if (!hasLocationFeature()) {
+            Log.d(TAG, "Skipping test as location is not supported");
+            return;
+        }
+        if (!isLocationEnabled()) {
+            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
+                    + " empty when location is disabled!");
+        }
         if (!mWifiManager.isWifiEnabled()) {
             setWifiEnabled(true);
         }
@@ -307,6 +318,18 @@
         }
     }
 
+    // Return true if location is enabled.
+    private boolean isLocationEnabled() {
+        return Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) !=
+                Settings.Secure.LOCATION_MODE_OFF;
+    }
+
+    // Returns true if the device has location feature.
+    private boolean hasLocationFeature() {
+        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
+    }
+
     /**
      * test point of wifiManager NetWork:
      * 1.add NetWork
diff --git a/tests/tests/os/jni/seccomp-tests/README.android b/tests/tests/os/jni/seccomp-tests/README.android
index 4c5bb83..8b1ac9a 100644
--- a/tests/tests/os/jni/seccomp-tests/README.android
+++ b/tests/tests/os/jni/seccomp-tests/README.android
@@ -11,3 +11,7 @@
 - Add get_seccomp_test_list()
 
 The diff of modifications can be found in local-modifications-android.diff.
+
+Additional modification is to backport fixes for Android Native Bridge:
+https://patchwork.kernel.org/patch/7537891/. This is not found in the above
+diff file. The patch is located in local-modifications-strict-args-fd88d16.diff.
diff --git a/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
new file mode 100644
index 0000000..a289147
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
@@ -0,0 +1,102 @@
+diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+index 98b0231..3c238e6 100644
+--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
++++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+@@ -28,6 +28,9 @@
+ #include <string.h>
+ #include <linux/elf.h>
+ #include <sys/uio.h>
++#include <fcntl.h>  // ANDROID
++#include <sys/mman.h>
++#include <sys/times.h>
+ 
+ #define _GNU_SOURCE
+ #include <unistd.h>
+@@ -386,14 +389,16 @@ TEST_SIGNAL(KILL_one, SIGSYS) {
+ }
+ 
+ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
++	void *fatal_address;
+ 	struct sock_filter filter[] = {
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ 			offsetof(struct seccomp_data, nr)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 		/* Only both with lower 32-bit for now. */
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
++			(unsigned long)&fatal_address, 0, 1),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 	};
+@@ -403,23 +408,29 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+ 	};
+ 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ 	pid_t parent = getppid();
+-	pid_t pid = getpid();
++	struct tms timebuf;
++	clock_t clock = times(&timebuf);
+ 	ASSERT_EQ(0, ret);
+ 
+ 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ 	ASSERT_EQ(0, ret);
+ 
+ 	EXPECT_EQ(parent, syscall(__NR_getppid));
+-	EXPECT_EQ(pid, syscall(__NR_getpid));
+-	/* getpid() should never return. */
+-	EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
++	EXPECT_LE(clock, syscall(__NR_times, &timebuf));
++	/* times() should never return. */
++	EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
+ }
+ 
+ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
++#ifndef __NR_mmap2
++	int sysno = __NR_mmap;
++#else
++	int sysno = __NR_mmap2;
++#endif
+ 	struct sock_filter filter[] = {
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ 			offsetof(struct seccomp_data, nr)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 		/* Only both with lower 32-bit for now. */
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
+@@ -433,16 +444,29 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+ 	};
+ 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ 	pid_t parent = getppid();
+-	pid_t pid = getpid();
++	int fd;
++	void *map1, *map2;
+ 	ASSERT_EQ(0, ret);
+ 
+ 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ 	ASSERT_EQ(0, ret);
+ 
++	fd = open("/dev/zero", O_RDONLY);
++	ASSERT_NE(-1, fd);
++
+ 	EXPECT_EQ(parent, syscall(__NR_getppid));
+-	EXPECT_EQ(pid, syscall(__NR_getpid));
+-	/* getpid() should never return. */
+-	EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
++	map1 = (void *)syscall(sysno,
++		NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
++	EXPECT_NE(MAP_FAILED, map1);
++	/* mmap2() should never return. */
++	map2 = (void *)syscall(sysno,
++		 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
++	EXPECT_EQ(MAP_FAILED, map2);
++
++	/* The test failed, so clean up the resources. */
++	munmap(map1, PAGE_SIZE);
++	munmap(map2, PAGE_SIZE);
++	close(fd);
+ }
+ 
+ /* TODO(wad) add 64-bit versus 32-bit arg tests. */
diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
index 98b0231..3c238e6 100644
--- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
+++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
@@ -28,6 +28,9 @@
 #include <string.h>
 #include <linux/elf.h>
 #include <sys/uio.h>
+#include <fcntl.h>  // ANDROID
+#include <sys/mman.h>
+#include <sys/times.h>
 
 #define _GNU_SOURCE
 #include <unistd.h>
@@ -386,14 +389,16 @@
 }
 
 TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+	void *fatal_address;
 	struct sock_filter filter[] = {
 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
 			offsetof(struct seccomp_data, nr)),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 		/* Only both with lower 32-bit for now. */
 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
+			(unsigned long)&fatal_address, 0, 1),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 	};
@@ -403,23 +408,29 @@
 	};
 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
 	pid_t parent = getppid();
-	pid_t pid = getpid();
+	struct tms timebuf;
+	clock_t clock = times(&timebuf);
 	ASSERT_EQ(0, ret);
 
 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
 	ASSERT_EQ(0, ret);
 
 	EXPECT_EQ(parent, syscall(__NR_getppid));
-	EXPECT_EQ(pid, syscall(__NR_getpid));
-	/* getpid() should never return. */
-	EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
+	EXPECT_LE(clock, syscall(__NR_times, &timebuf));
+	/* times() should never return. */
+	EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
 }
 
 TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+#ifndef __NR_mmap2
+	int sysno = __NR_mmap;
+#else
+	int sysno = __NR_mmap2;
+#endif
 	struct sock_filter filter[] = {
 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
 			offsetof(struct seccomp_data, nr)),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 		/* Only both with lower 32-bit for now. */
 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
@@ -433,16 +444,29 @@
 	};
 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
 	pid_t parent = getppid();
-	pid_t pid = getpid();
+	int fd;
+	void *map1, *map2;
 	ASSERT_EQ(0, ret);
 
 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
 	ASSERT_EQ(0, ret);
 
+	fd = open("/dev/zero", O_RDONLY);
+	ASSERT_NE(-1, fd);
+
 	EXPECT_EQ(parent, syscall(__NR_getppid));
-	EXPECT_EQ(pid, syscall(__NR_getpid));
-	/* getpid() should never return. */
-	EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
+	map1 = (void *)syscall(sysno,
+		NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
+	EXPECT_NE(MAP_FAILED, map1);
+	/* mmap2() should never return. */
+	map2 = (void *)syscall(sysno,
+		 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
+	EXPECT_EQ(MAP_FAILED, map2);
+
+	/* The test failed, so clean up the resources. */
+	munmap(map1, PAGE_SIZE);
+	munmap(map2, PAGE_SIZE);
+	close(fd);
 }
 
 /* TODO(wad) add 64-bit versus 32-bit arg tests. */
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index af60139..75ad865 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -29,7 +29,7 @@
 
     private static final String LOG_TAG = "BuildVersionTest";
     private static final Set<String> EXPECTED_RELEASES =
-            new HashSet<String>(Arrays.asList("6.0"));
+            new HashSet<String>(Arrays.asList("6.0.1", "6.0"));
     private static final int EXPECTED_SDK = 23;
     private static final String EXPECTED_BUILD_VARIANT = "user";
     private static final String EXPECTED_TAG = "release-keys";
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 0962bbd..1d0cfe6 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -785,7 +785,9 @@
                 new File("/dev/ashmem"),
                 new File("/dev/binder"),
                 new File("/dev/card0"),       // b/13159510
+                new File("/dev/renderD128"),
                 new File("/dev/dri/card0"),   // b/13159510
+                new File("/dev/dri/renderD128"),
                 new File("/dev/felica"),     // b/11142586
                 new File("/dev/felica_ant"), // b/11142586
                 new File("/dev/felica_cen"), // b/11142586
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
index 00cbfd8..fdc3058 100644
--- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -17,6 +17,7 @@
 package android.security.cts;
 
 import android.os.IBinder;
+import android.os.DeadObjectException;
 import android.os.TransactionTooLargeException;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -108,7 +109,7 @@
                     // probably not checking for DUMP.
                     throw e;
                 }
-            } catch (TransactionTooLargeException e) {
+            } catch (TransactionTooLargeException | DeadObjectException e) {
                 // SELinux likely prevented the dump - assume safe
                 continue;
             } finally {
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index d7fe239..1a2b415 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -246,7 +246,8 @@
         mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras);
 
         try {
-            if (!mInCallCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+            if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
                 fail("No call added to InCallService.");
             }
         } catch (InterruptedException e) {
@@ -297,7 +298,8 @@
         placeNewCallWithPhoneAccount(extras, videoState);
 
         try {
-            if (!mInCallCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+            if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
                 fail("No call added to InCallService.");
             }
         } catch (InterruptedException e) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
index 0b5fe61..eda193d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
@@ -77,7 +77,8 @@
         mContext.startActivity(intent);
 
         try {
-            if (callbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+            if (callbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
                 return;
             }
         } catch (InterruptedException e) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 4936209..d1a9723 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -33,6 +33,7 @@
     static final String TAG = "TelecomCTSTests";
     static final boolean HAS_TELECOM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
     static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
+    static final long WAIT_FOR_CALL_ADDED_TIMEOUT_S = 15;
 
     // Non-final to allow modification by tests not in this package (e.g. permission-related
     // tests in the Telecom2 test package.
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index d90e394..2db9ba1 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -301,11 +301,19 @@
         int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_32BIT_CHARS, false);
         assertEquals(3, result[0]);
         assertEquals(LONG_TEXT_WITH_32BIT_CHARS.length(), result[1]);
+        // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
+        // characters. We need to subtract one because a 32-bit character crosses the
+        // boundary of 2 parts.
+        int preMaxChars = 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1;
+        // If EMS is not supported, break down EMS into single segment SMS
+        // and add page info "x/y".
+        // In the case of UCS2 encoding type, we need 8 bytes for this
+        // but we only have 6 bytes from UDH, so truncate the limit for
+        // each segment by 2 bytes (1 char). This log sms has three segments,
+        // so truncate the limit by 3 char in total
+        int maxChars = SmsMessage.hasEmsSupport() ? preMaxChars : preMaxChars - 3;
         assertRemaining(LONG_TEXT_WITH_32BIT_CHARS.length(), result[2],
-                // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
-                // characters. We need to subtract one because a 32-bit character crosses the
-                // boundary of 2 parts.
-                3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1);
+                maxChars);
         assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
     }
 
diff --git a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
index 4262a31..72a8e72 100644
--- a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
@@ -19,6 +19,7 @@
 
 import android.cts.util.PollingCheck;
 import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
 import android.provider.Settings.SettingNotFoundException;
 import android.provider.Settings.System;
 import android.test.ActivityInstrumentationTestCase2;
@@ -31,6 +32,10 @@
 import android.widget.LinearLayout;
 import android.widget.LinearLayout.LayoutParams;
 
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+
 /**
  * Test {@link PasswordTransformationMethod}.
  */
@@ -97,10 +102,39 @@
         mEditText = (EditText) getActivity().findViewById(EDIT_TXT_ID);
         assertTrue(mEditText.isFocused());
 
+        enableAppOps();
         savePasswordPref();
         switchShowPassword(true);
     }
 
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:write_settings allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(getInstrumentation().getContext().getPackageName());
+        query.append(" android:write_settings");
+        String queryStr = query.toString();
+
+        String result = "No operations.";
+        while (result.contains("No operations")) {
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+                                        queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+
+    private String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : "";
+        }
+    }
+
     @Override
     protected void tearDown() throws Exception {
         resumePasswordPref();
diff --git a/tools/cts-media/get_achievable_rates.py b/tools/cts-media/get_achievable_rates.py
new file mode 100755
index 0000000..81412da
--- /dev/null
+++ b/tools/cts-media/get_achievable_rates.py
@@ -0,0 +1,396 @@
+#!/usr/bin/python
+# 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.
+#
+
+import argparse, math, re, sys
+import xml.etree.ElementTree as ET
+from collections import defaultdict, namedtuple
+import itertools
+
+
+def createLookup(values, key):
+  """Creates a lookup table for a collection of values based on keys.
+
+  Arguments:
+    values: a collection of arbitrary values. Must be iterable.
+    key: a function of one argument that returns the key for a value.
+
+  Returns:
+    A dict mapping keys (as generated by the key argument) to lists of
+    values. All values in the lists have the same key, and are in the order
+    they appeared in the collection.
+  """
+  lookup = defaultdict(list)
+  for v in values:
+    lookup[key(v)].append(v)
+  return lookup
+
+
+def _intify(value):
+  """Returns a value converted to int if possible, else the original value."""
+  try:
+    return int(value)
+  except ValueError:
+    return value
+
+
+class Size(namedtuple('Size', ['width', 'height'])):
+  """A namedtuple with width and height fields."""
+  def __str__(self):
+    return '%dx%d' % (self.width, self.height)
+
+
+class _VideoResultBase(object):
+  """Helper methods for results. Not for use by applications.
+
+  Attributes:
+    codec: The name of the codec (string) or None
+    size: Size representing the video size or None
+    mime: The mime-type of the codec (string) or None
+    rates: The measured achievable frame rates
+    is_decoder: True iff codec is a decoder.
+  """
+
+  def __init__(self, is_decoder):
+    self.codec = None
+    self.mime = None
+    self.size = None
+    self._rates_from_failure = []
+    self._rates_from_message = []
+    self.is_decoder = is_decoder
+
+  def _inited(self):
+    """Returns true iff codec, mime and size was set."""
+    return None not in (self.codec, self.mime, self.size)
+
+  def __len__(self):
+    # don't report any result if codec name, mime type and size is unclear
+    if not self._inited():
+      return 0
+    return len(self.rates)
+
+  @property
+  def rates(self):
+    return self._rates_from_failure or self._rates_from_message
+
+  def _parseDict(self, value):
+    """Parses a MediaFormat from its string representation sans brackets."""
+    return dict((k, _intify(v))
+                for k, v in re.findall(r'([^ =]+)=([^ [=]+(?:|\[[^\]]+\]))(?:, |$)', value))
+
+  def _cleanFormat(self, format):
+    """Removes internal fields from a parsed MediaFormat."""
+    format.pop('what', None)
+    format.pop('image-data', None)
+
+  MESSAGE_PATTERN = r'(?P<key>\w+)=(?P<value>\{[^}]*\}|[^ ,{}]+)'
+
+  def _parsePartialResult(self, message_match):
+    """Parses a partial test result conforming to the message pattern.
+
+    Returns:
+      A tuple of string key and int, string or dict value, where dict has
+      string keys mapping to int or string values.
+    """
+    key, value = message_match.group('key', 'value')
+    if value.startswith('{'):
+      value = self._parseDict(value[1:-1])
+      if key.endswith('Format'):
+        self._cleanFormat(value)
+    else:
+      value = _intify(value)
+    return key, value
+
+  def _parseValuesFromBracket(self, line):
+    """Returns the values enclosed in brackets without the brackets.
+
+    Parses a line matching the pattern "<tag>: [<values>]" and returns <values>.
+
+    Raises:
+      ValueError: if the line does not match the pattern.
+    """
+    try:
+      return re.match(r'^[^:]+: *\[(?P<values>.*)\]\.$', line).group('values')
+    except AttributeError:
+      raise ValueError('line does not match "tag: [value]": %s' % line)
+
+  def _parseRawData(self, line):
+    """Parses the raw data line for video performance tests.
+
+    Yields:
+      Dict objects corresponding to parsed results, mapping string keys to
+      int, string or dict values.
+    """
+    try:
+      values = self._parseValuesFromBracket(line)
+      result = {}
+      for m in re.finditer(self.MESSAGE_PATTERN + r'(?P<sep>,? +|$)', values):
+        key, value = self._parsePartialResult(m)
+        result[key] = value
+        if m.group('sep') != ' ':
+          yield result
+          result = {}
+    except ValueError:
+      print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+  def _tryParseMeasuredFrameRate(self, line):
+    """Parses a line starting with 'Measured frame rate:'."""
+    if line.startswith('Measured frame rate: '):
+      try:
+        values = self._parseValuesFromBracket(line)
+        values = re.split(r' *, *', values)
+        self._rates_from_failure = list(map(float, values))
+      except ValueError:
+        print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+  def parse(self, test):
+    """Parses the ValueArray and FailedScene lines of a test result.
+
+    Arguments:
+      test: An ElementTree <Test> element.
+    """
+    failure = test.find('FailedScene')
+    if failure is not None:
+      trace = failure.find('StackTrace')
+      if trace is not None:
+        for line in re.split(r'[\r\n]+', trace.text):
+          self._parseFailureLine(line)
+    details = test.find('Details')
+    if details is not None:
+      for array in details.iter('ValueArray'):
+        message = array.get('message')
+        self._parseMessage(message, array)
+
+  def _parseFailureLine(self, line):
+    raise NotImplementedError
+
+  def _parseMessage(self, message, array):
+    raise NotImplementedError
+
+  def getData(self):
+    """Gets the parsed test result data.
+
+    Yields:
+       Result objects containing at least codec, size, mime and rates attributes."""
+    yield self
+
+
+class VideoEncoderDecoderTestResult(_VideoResultBase):
+  """Represents a result from a VideoEncoderDecoderTest performance case."""
+
+  def __init__(self, unused_m):
+    super(VideoEncoderDecoderTestResult, self).__init__(is_decoder=False)
+
+  # If a VideoEncoderDecoderTest succeeds, it provides the results in the
+  # message of a ValueArray. If fails, it provides the results in the failure
+  # using raw data. (For now it also includes some data in the ValueArrays even
+  # if it fails, which we ignore.)
+
+  def _parseFailureLine(self, line):
+    """Handles parsing a line from the failure log."""
+    self._tryParseMeasuredFrameRate(line)
+
+  def _parseMessage(self, message, array):
+    """Handles parsing a message from ValueArrays."""
+    if message.startswith('codec='):
+      result = dict(self._parsePartialResult(m)
+                  for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+      if 'EncInputFormat' in result:
+        self.codec = result['codec']
+        fmt = result['EncInputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.mime = result['EncOutputFormat']['mime']
+        self._rates_from_message.append(1000000./result['min'])
+
+
+class VideoDecoderPerfTestResult(_VideoResultBase):
+  """Represents a result from a VideoDecoderPerfTest performance case."""
+
+  # If a VideoDecoderPerfTest succeeds, it provides the results in the message
+  # of a ValueArray. If fails, it provides the results in the failure only
+  # using raw data.
+
+  def __init__(self, unused_m):
+    super(VideoDecoderPerfTestResult, self).__init__(is_decoder=True)
+
+  def _parseFailureLine(self, line):
+    """Handles parsing a line from the failure log."""
+    self._tryParseMeasuredFrameRate(line)
+    # if the test failed, we can only get the codec/size/mime from the raw data.
+    if line.startswith('Raw data: '):
+      for result in self._parseRawData(line):
+        fmt = result['DecOutputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.codec = result['codec']
+        self.mime = result['mime']
+
+  def _parseMessage(self, message, array):
+    """Handles parsing a message from ValueArrays."""
+    if message.startswith('codec='):
+      result = dict(self._parsePartialResult(m)
+                  for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+      if result.get('decodeto') == 'surface':
+        self.codec = result['codec']
+        fmt = result['DecOutputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.mime = result['mime']
+        self._rates_from_message.append(1000000. / result['min'])
+
+
+class Results(object):
+  """Container that keeps all test results."""
+  def __init__(self):
+      self._results = [] # namedtuples
+      self._device = None
+
+  VIDEO_ENCODER_DECODER_TEST_REGEX = re.compile(
+      'test(.*)(\d{4})x(\d{4})(Goog|Other)$')
+
+  VIDEO_DECODER_PERF_TEST_REGEX = re.compile(
+      'test(VP[89]|H26[34]|MPEG4|HEVC)(\d+)x(\d+)(.*)$')
+
+  TestCaseSpec = namedtuple('TestCaseSpec', 'package path class_ regex result_class')
+
+  def _getTestCases(self):
+    return [
+      self.TestCaseSpec(package='CtsDeviceVideoPerf',
+                   path='TestSuite/TestSuite/TestSuite/TestSuite/TestCase',
+                   class_='VideoEncoderDecoderTest',
+                   regex=self.VIDEO_ENCODER_DECODER_TEST_REGEX,
+                   result_class=VideoEncoderDecoderTestResult),
+      self.TestCaseSpec(package='CtsMediaTestCases',
+                   path='TestSuite/TestSuite/TestSuite/TestCase',
+                   class_='VideoDecoderPerfTest',
+                   regex=self.VIDEO_DECODER_PERF_TEST_REGEX,
+                   result_class=VideoDecoderPerfTestResult)
+    ]
+
+  def _verifyDeviceInfo(self, device):
+    assert self._device in (None, device), "expected %s device" % self._device
+    self._device = device
+
+  def importXml(self, xml):
+    self._verifyDeviceInfo(xml.find('DeviceInfo/BuildInfo').get('buildName'))
+
+    packages = createLookup(self._getTestCases(), lambda tc: tc.package)
+
+    for pkg in xml.iter('TestPackage'):
+      tests_in_package = packages.get(pkg.get('name'))
+      if not tests_in_package:
+        continue
+      paths = createLookup(tests_in_package, lambda tc: tc.path)
+      for path, tests_in_path in paths.items():
+        classes = createLookup(tests_in_path, lambda tc: tc.class_)
+        for tc in pkg.iterfind(path):
+          tests_in_class = classes.get(tc.get('name'))
+          if not tests_in_class:
+            continue
+          for test in tc.iter('Test'):
+            for tc in tests_in_class:
+              m = tc.regex.match(test.get('name'))
+              if m:
+                result = tc.result_class(m)
+                result.parse(test)
+                self._results.append(result)
+
+  def importFile(self, path):
+    print >> sys.stderr, 'Importing "%s"...' % path
+    try:
+      return self.importXml(ET.parse(path))
+    except ET.ParseError:
+      raise ValueError('not a valid XML file')
+
+  def getData(self):
+    for result in self._results:
+      for data in result.getData():
+        yield data
+
+  def dumpXml(self, results):
+    yield '<?xml version="1.0" encoding="utf-8" ?>'
+    yield '<!-- Copyright 2015 The Android Open Source Project'
+    yield ''
+    yield '     Licensed under the Apache License, Version 2.0 (the "License");'
+    yield '     you may not use this file except in compliance with the License.'
+    yield '     You may obtain a copy of the License at'
+    yield ''
+    yield '          http://www.apache.org/licenses/LICENSE-2.0'
+    yield ''
+    yield '     Unless required by applicable law or agreed to in writing, software'
+    yield '     distributed under the License is distributed on an "AS IS" BASIS,'
+    yield '     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.'
+    yield '     See the License for the specific language governing permissions and'
+    yield '     limitations under the License.'
+    yield '-->'
+    yield ''
+    yield '<MediaCodecs>'
+    last_section = None
+    Comp = namedtuple('Comp', 'is_decoder google mime name')
+    by_comp = createLookup(results,
+                           lambda e: Comp(is_decoder=e.is_decoder, google='.google.' in e.codec, mime=e.mime, name=e.codec))
+    for comp in sorted(by_comp):
+      section = 'Decoders' if comp.is_decoder else 'Encoders'
+      if section != last_section:
+        if last_section:
+          yield '    </%s>' % last_section
+        yield '    <%s>' % section
+        last_section = section
+      yield '        <MediaCodec name="%s" type="%s" update="true">' % (comp.name, comp.mime)
+      by_size = createLookup(by_comp[comp], lambda e: e.size)
+      for size in sorted(by_size):
+        values = list(itertools.chain(*(e.rates for e in by_size[size])))
+        min_, max_ = min(values), max(values)
+        med_ = int(math.sqrt(min_ * max_))
+        yield '            <Limit name="measured-frame-rate-%s" range="%d-%d" />' % (size, med_, med_)
+      yield '        </MediaCodec>'
+    if last_section:
+      yield '    </%s>' % last_section
+    yield '</MediaCodecs>'
+
+
+class Main(object):
+  """Executor of this utility."""
+
+  def __init__(self):
+    self._result = Results()
+
+    self._parser = argparse.ArgumentParser('get_achievable_framerates')
+    self._parser.add_argument('result_xml', nargs='+')
+
+  def _parseArgs(self):
+    self._args = self._parser.parse_args()
+
+  def _importXml(self, xml):
+    self._result.importFile(xml)
+
+  def _report(self):
+    for line in self._result.dumpXml(r for r in self._result.getData() if r):
+      print line
+
+  def run(self):
+    self._parseArgs()
+    try:
+      for xml in self._args.result_xml:
+        try:
+          self._importXml(xml)
+        except (ValueError, IOError, AssertionError) as e:
+          print >> sys.stderr, e
+          raise KeyboardInterrupt
+      self._report()
+    except KeyboardInterrupt:
+      print >> sys.stderr, 'Interrupted.'
+
+if __name__ == '__main__':
+  Main().run()
+
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 782e6ab..a39d8b6 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
     @Option(name="cts-install-path", description="the path to the cts installation to use")
     private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
 
-    public static final String CTS_BUILD_VERSION = "6.0_r1";
+    public static final String CTS_BUILD_VERSION = "6.0_r2";
     public static final String CTS_PACKAGE = "com.android.cts.tradefed.testtype";
 
     /**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 51b457d..3efc7fc 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -432,6 +432,9 @@
         serializer.attribute(ns, "endtime", endTime);
         serializer.attribute(ns, "version", CTS_RESULT_FILE_VERSION);
         serializer.attribute(ns, "suite", mSuiteName);
+        if (mReferenceUrl != null) {
+            serializer.attribute(ns, "referenceUrl", mReferenceUrl);
+        }
         mResults.serialize(serializer, mBuildInfo.getBuildId());
         // TODO: not sure why, but the serializer doesn't like this statement
         //serializer.endTag(ns, RESULT_TAG);
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index 51a6153..958dbe4 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -48,8 +48,9 @@
  */
 public class CtsXmlResultReporterTest extends TestCase {
 
+    private static final String TEST_SUMMARY_URL = "http://www.google.com?q=android";
     private static final List<TestSummary> SUMMARY_LIST =
-            new ArrayList<>(Arrays.asList(new TestSummary("TEST_SUMMARY_URL")));
+            new ArrayList<>(Arrays.asList(new TestSummary(TEST_SUMMARY_URL)));
     private CtsXmlResultReporter mResultReporter;
     private ByteArrayOutputStream mOutputStream;
     private File mBuildDir;
@@ -116,7 +117,7 @@
             "<?xml-stylesheet type=\"text/xsl\" href=\"cts_result.xsl\"?>";
         final String expectedTestOutput = String.format(
             "<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
-                    "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS" );
+                    "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS");
         final String expectedSummaryOutput =
             "<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"0\" />";
         final String expectedEndTag = "</TestResult>";
@@ -128,7 +129,7 @@
         assertTrue(String.format("test output did not contain expected test result [%s]. Got %s",
                 expectedTestOutput, actualOutput), actualOutput.contains(expectedTestOutput));
         assertTrue(String.format("test output did not contain expected test summary [%s]. Got %s",
-                expectedTestOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
+                expectedSummaryOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
         assertTrue(String.format("test output did not contain expected TestResult end tag. Got %s",
                 actualOutput), actualOutput.endsWith(expectedEndTag));
         EasyMock.verify(mMockBuild);
@@ -146,10 +147,15 @@
         mResultReporter.testStarted(testId);
         mResultReporter.testEnded(testId, emptyMap);
         mResultReporter.testRunEnded(3000, emptyMap);
-        mResultReporter.invocationEnded(1);
         mResultReporter.putSummary(SUMMARY_LIST);
+        mResultReporter.invocationEnded(1);
         String output =  getOutput();
         // TODO: consider doing xml based compare
+        final String expectedTestOutput = String.format(
+            "<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
+                    "version=\"%s\" suite=\"%s\" referenceUrl=\"%s\"> ",
+                            CTS_RESULT_FILE_VERSION, "CTS", TEST_SUMMARY_URL);
+        assertTrue("Found output: " + output, output.contains(expectedTestOutput));
         assertTrue(output.contains(
               "<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"1\" />"));
         assertTrue(output.contains("<TestPackage name=\"\" appPackageName=\"run\" abi=\"" +