Merge "Move EGL setup to separate function." into mnc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 4d30dda..41f9dc3 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -100,6 +100,7 @@
     CtsManagedProfileApp \
     CtsMonkeyApp \
     CtsMonkeyApp2 \
+    CtsPackageInstallerApp \
     CtsPermissionApp \
     CtsSimpleApp \
     CtsSimplePreMApp \
@@ -176,6 +177,7 @@
     CtsNdefTestCases \
     CtsNetTestCases \
     CtsNetTestCasesLegacyApi22 \
+    CtsNetTestCasesLegacyPermission22 \
     CtsOpenGLTestCases \
     CtsOpenGlPerfTestCases \
     CtsOsTestCases \
diff --git a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
index 6c2b5c1..e176312 100644
--- a/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_burst_sensitivity.py
@@ -44,6 +44,8 @@
 
         # Expose for the scene with min sensitivity
         sens_min, sens_max = props['android.sensor.info.sensitivityRange']
+        # Digital gains might not be visible on RAW data
+        sens_max = props['android.sensor.maxAnalogSensitivity']
         sens_step = (sens_max - sens_min) / NUM_STEPS
         s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
index 14c5eb0..cc0ce14 100644
--- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
@@ -42,6 +42,8 @@
 
         # Expose for the scene with min sensitivity
         sens_min, sens_max = props['android.sensor.info.sensitivityRange']
+        # Digital gains might not be visible on RAW data
+        sens_max = props['android.sensor.maxAnalogSensitivity']
         sens_step = (sens_max - sens_min) / NUM_STEPS
         s_ae,e_ae,_,_,_  = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 217913c..5c188b7 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1452,6 +1452,9 @@
         <activity android:name=".managedprovisioning.CrossProfileTestActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.CROSS_PROFILE" />
+                <!-- We need to have at least one activity listening to this intent in the parent
+                     to test if it is forwarded from the managed profile to the parent -->
+                <action android:name="android.provider.MediaStore.RECORD_SOUND" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index c5469a7..77566a3 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1454,11 +1454,15 @@
         This test exercises Keyguard Disabled Features. Follow instructions above.
     </string>
     <string name="provisioning_byod_keyguard_disabled_features_instruction">
-        Please press the \"Prepare test\" button to disable trust agents.\n
+        Please go to Settings &gt; Security &gt; Device administrators and set
+        \"CTS Verifier - AfW Admin\" as active admin.\n
+        After that please press the \"Prepare test\" button to disable trust agents.\n
         Then please press through the following verification steps.\n
-        Note: Device password will be set to \"testpassword\". After leaving the screen device password be cleared.
+        Note: Device password will be set to \"testpassword\". After leaving the screen device
+        password and active admin status will be cleared.
     </string>
     <string name="provisioning_byod_keyguard_disabled_features_prepare_button">Prepare test</string>
+    <string name="provisioning_byod_keyguard_disabled_features_not_admin">CtsVerifier is not active admin. Please follow instructions.</string>
     <string name="provisioning_byod_disable_trust_agents">Disable trust agents</string>
     <string name="provisioning_byod_disable_trust_agents_instruction">
         Please press the Go button to go to Settings > Security. Then go to Trusted agents and\n
@@ -1525,6 +1529,10 @@
         - Both Personal and Work categories exist.\n
         - \"Remove work profile\" exists under the Work category.\n
         \n
+        Furthermore, hit the action overflow button (3 dots) and verify that:\n
+        - There are two auto-sync options present, one for personal and one for work data.\n
+        - De-selecting either option prompts a warning dialog.\n
+        \n
         Use the Back button to return to this page.
     </string>
     <string name="provisioning_byod_admin_visible_instruction">
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 3fec414..3d7d42d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -160,6 +160,8 @@
                             IntentFiltersTestHelper.FLAG_INTENTS_FROM_MANAGED);
             setResult(intentFiltersSetForManagedIntents? RESULT_OK : RESULT_FAILED, null);
         } else if (action.equals(ACTION_CAPTURE_AND_CHECK_IMAGE)) {
+            // We need the camera permission to send the image capture intent.
+            grantCameraPermissionToSelf();
             Intent captureImageIntent = getCaptureImageIntent();
             mImageUri = getTempUri("image.jpg");
             captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
@@ -172,6 +174,8 @@
             }
             return;
         } else if (action.equals(ACTION_CAPTURE_AND_CHECK_VIDEO)) {
+            // We need the camera permission to send the video capture intent.
+            grantCameraPermissionToSelf();
             Intent captureVideoIntent = getCaptureVideoIntent();
             mVideoUri = getTempUri("video.mp4");
             captureVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mVideoUri);
@@ -336,6 +340,12 @@
         Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
     }
 
+    private void grantCameraPermissionToSelf() {
+        mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
+                android.Manifest.permission.CAMERA,
+                DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+    }
+
     @Override
     public void onDialogClose() {
         finish();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index 579cbcc..7dc99c0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
+import android.app.DownloadManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -133,6 +134,13 @@
                 Intent.CATEGORY_OPENABLE),
         new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*").addCategory(
                 Intent.CATEGORY_OPENABLE),
+        new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
+        new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
+        new Intent(Settings.ACTION_APPLICATION_SETTINGS),
+        new Intent("android.settings.ACTION_OTHER_SOUND_SETTINGS"),
+        new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION),
+        new Intent(Settings.ACTION_WIFI_IP_SETTINGS),
+        new Intent(Settings.ACTION_WIFI_SETTINGS),
         new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
     };
 
@@ -155,7 +163,6 @@
         new Intent(Intent.ACTION_VIEW).setData(
                 Uri.parse("http://www.example.com/horse.mp3")).setType("audio/*"),
         new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH),
-        new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION),
         new Intent(Intent.ACTION_VIEW).setData(
                 Uri.parse("market://details?id=com.android.chrome")).addCategory(
                 Intent.CATEGORY_BROWSABLE),
@@ -163,17 +170,12 @@
         new Intent(Settings.ACTION_SEARCH_SETTINGS),
         new Intent(Settings.ACTION_PRINT_SETTINGS),
         new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE),
-        new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
-        new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
-        new Intent(Settings.ACTION_APPLICATION_SETTINGS),
         new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
                 Uri.parse("package:com.android.chrome")),
-        new Intent("android.settings.ACTION_OTHER_SOUND_SETTINGS"),
-        new Intent(Settings.ACTION_WIFI_IP_SETTINGS),
-        new Intent(Settings.ACTION_WIFI_SETTINGS),
         new Intent("android.settings.SHOW_INPUT_METHOD_PICKER"),
         new Intent(Intent.ACTION_INSERT).setData(Events.CONTENT_URI),
-        new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
+        new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL),
+        new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)
     };
 
     // This flag specifies we are dealing with intents fired from the primary profile.
@@ -306,4 +308,4 @@
         }
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
index 0fdc498..1a158f8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
@@ -18,6 +18,7 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.fingerprint.FingerprintManager;
@@ -25,6 +26,7 @@
 import android.provider.Settings;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.widget.Toast;
 
 import com.android.cts.verifier.ArrayTestListAdapter;
 import com.android.cts.verifier.DialogTestListActivity;
@@ -32,6 +34,8 @@
 
 public class KeyguardDisabledFeaturesActivity extends DialogTestListActivity {
 
+    private DevicePolicyManager mDpm;
+
     public KeyguardDisabledFeaturesActivity() {
         super(R.layout.provisioning_byod,
                 R.string.provisioning_byod_keyguard_disabled_features,
@@ -43,12 +47,20 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+
         mPrepareTestButton.setText(
                 R.string.provisioning_byod_keyguard_disabled_features_prepare_button);
         mPrepareTestButton.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    resetPassword("testpassword");
+                    if (!mDpm.isAdminActive(DeviceAdminTestReceiver.getReceiverComponentName())) {
+                        Toast.makeText(KeyguardDisabledFeaturesActivity.this,
+                                R.string.provisioning_byod_keyguard_disabled_features_not_admin,
+                                Toast.LENGTH_SHORT).show();
+                        return;
+                    }
+                    mDpm.resetPassword("testpassword", 0);
                     setKeyguardDisabledFeatures(DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS |
                             DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
                             DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
@@ -60,7 +72,11 @@
     public void finish() {
         // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
         // clear the password.
-        resetPassword(null);
+        final ComponentName adminComponent = DeviceAdminTestReceiver.getReceiverComponentName();
+        if (mDpm.isAdminActive(adminComponent)) {
+            mDpm.resetPassword(null, 0);
+            mDpm.removeActiveAdmin(adminComponent);
+        }
         super.finish();
     }
 
@@ -71,16 +87,6 @@
         startActivity(setKeyguardDisabledFeaturesIntent);
     }
 
-    /**
-     * Reset device password
-     * @param password password to reset to (may be null)
-     */
-    private void resetPassword(String password) {
-        DevicePolicyManager dpm = (DevicePolicyManager)
-                getSystemService(Context.DEVICE_POLICY_SERVICE);
-        dpm.resetPassword(password, 0);
-    }
-
     @Override
     protected void setupTests(ArrayTestListAdapter adapter) {
         adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_disable_trust_agents,
diff --git a/build/device_info_package.mk b/build/device_info_package.mk
index 600f6a1..0aaa8aa 100644
--- a/build/device_info_package.mk
+++ b/build/device_info_package.mk
@@ -19,7 +19,7 @@
 DEVICE_INFO_PACKAGE := com.android.compatibility.common.deviceinfo
 DEVICE_INFO_INSTRUMENT := com.android.compatibility.common.deviceinfo.DeviceInfoInstrument
 DEVICE_INFO_PERMISSIONS += android.permission.WRITE_EXTERNAL_STORAGE
-DEVICE_INFO_ACTIVITIES += $(DEVICE_INFO_PACKAGE).GenericDeviceInfo
+DEVICE_INFO_ACTIVITIES += $(DEVICE_INFO_PACKAGE).GenericDeviceInfo $(DEVICE_INFO_PACKAGE).PackageDeviceInfo
 
 # Add the base device info
 LOCAL_STATIC_JAVA_LIBRARIES += compatibility-device-info
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java
index f3af0bc..2f80911 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.java
@@ -25,19 +25,37 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * An instrumentation that runs all activities that extends DeviceInfoActivity.
  */
 public class DeviceInfoInstrument extends Instrumentation {
 
     private static final String LOG_TAG = "ExtendedDeviceInfo";
-    private static final int DEVICE_INFO_ACTIVITY_REQUEST = 1;
+    private static final String COLLECTOR = "collector";
 
+    // List of collectors to run. If null or empty, all collectors will run.
+    private Set<String> mCollectorSet = new HashSet<String>();
+
+    // Results sent to the caller when this istrumentation completes.
     private Bundle mBundle = new Bundle();
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (savedInstanceState != null) {
+            String collectorList = savedInstanceState.getString(COLLECTOR);
+            if (!TextUtils.isEmpty(collectorList)) {
+                for (String collector : TextUtils.split(collectorList, ",")) {
+                  if (!TextUtils.isEmpty(collector)) {
+                    mCollectorSet.add(collector);
+                  }
+                }
+            }
+        }
         start();
     }
 
@@ -47,13 +65,8 @@
             Context context = getContext();
             ActivityInfo[] activities = context.getPackageManager().getPackageInfo(
                     context.getPackageName(), PackageManager.GET_ACTIVITIES).activities;
-
             for (ActivityInfo activityInfo : activities) {
-                Class cls = Class.forName(activityInfo.name);
-                if (cls != DeviceInfoActivity.class &&
-                        DeviceInfoActivity.class.isAssignableFrom(cls)) {
-                    runActivity(activityInfo.name);
-                }
+                runActivity(activityInfo.name);
             }
         } catch (Exception e) {
             Log.e(LOG_TAG, "Exception occurred while running activities.", e);
@@ -65,9 +78,40 @@
     }
 
     /**
+     * Returns true if the activity meets the criteria to run; otherwise, false.
+     */
+    private boolean isActivityRunnable(Class activityClass) {
+        // Don't run the base DeviceInfoActivity class.
+        if (DeviceInfoActivity.class == activityClass) {
+            return false;
+        }
+        // Don't run anything that doesn't extends DeviceInfoActivity.
+        if (!DeviceInfoActivity.class.isAssignableFrom(activityClass)) {
+            return false;
+        }
+        // Only run activity if mCollectorSet is empty or contains it.
+        if (mCollectorSet != null && mCollectorSet.size() > 0) {
+            return mCollectorSet.contains(activityClass.getName());
+        }
+        // Run anything that makes it here.
+        return true;
+    }
+
+    /**
      * Runs a device info activity and return the file path where the results are written to.
      */
     private void runActivity(String activityName) throws Exception {
+        Class activityClass = null;
+        try {
+            activityClass = Class.forName(activityName);
+        } catch (ClassNotFoundException e) {
+            return;
+        }
+
+        if (activityClass == null || !isActivityRunnable(activityClass)) {
+            return;
+        }
+
         Intent intent = new Intent();
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.setClassName(this.getContext(), activityName);
@@ -76,7 +120,7 @@
         waitForIdleSync();
         activity.waitForActivityToFinish();
 
-        String className = Class.forName(activityName).getSimpleName();
+        String className = activityClass.getSimpleName();
         String errorMessage = activity.getErrorMessage();
         if (TextUtils.isEmpty(errorMessage)) {
             mBundle.putString(className, activity.getResultFilePath());
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
new file mode 100644
index 0000000..4d9ad46
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+
+/**
+ * PackageDeviceInfo collector.
+ */
+public class PackageDeviceInfo extends DeviceInfoActivity {
+
+    private static final String PACKAGE = "package";
+    private static final String NAME = "name";
+    private static final String VERSION_NAME = "version_name";
+    private static final String SYSTEM_PRIV = "system_priv";
+    private static final String PRIV_APP_DIR = "/system/priv-app";
+
+    @Override
+    protected void collectDeviceInfo() {
+        PackageManager pm = this.getPackageManager();
+        startArray(PACKAGE);
+        for (PackageInfo pkg : pm.getInstalledPackages(0)) {
+            startGroup();
+            addResult(NAME, pkg.packageName);
+            addResult(VERSION_NAME, pkg.versionName);
+
+            String dir = pkg.applicationInfo.sourceDir;
+            addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
+            endGroup();
+        }
+        endArray(); // Package
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
index ed920e9..fe07bcb 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
@@ -33,6 +33,15 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
             </intent-filter>
         </receiver>
+        <receiver
+            android:name="com.android.cts.deviceandprofileowner.PrimaryUserDeviceAdmin"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/primary_device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
         <activity
             android:name="com.android.cts.deviceandprofileowner.ApplicationRestrictionsActivity" />
         <activity
@@ -62,6 +71,13 @@
                        android:resource="@xml/authenticator" />
         </service>
 
+        <activity android:name=".UserRestrictionActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml
new file mode 100644
index 0000000..a6aff49
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml
@@ -0,0 +1,20 @@
+<!-- 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.
+-->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies>
+         <reset-password />
+         <limit-password />
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
similarity index 96%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DelegatedCertInstallerTest.java
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index de859b4..3eb8c35 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.cts.managedprofile;
+package com.android.cts.deviceandprofileowner;
 
 import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
@@ -40,14 +40,12 @@
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
-import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
-
 /**
  * Exercise delegated cert installer APIs in {@link DevicePolicyManager} by setting the test app
  * (CtsCertInstallerApp) as a delegated cert installer and then asking it to invoke various
  * cert-related APIs. The expected certificate changes are validated both remotely and locally.
  */
-public class DelegatedCertInstallerTest extends AndroidTestCase {
+public class DelegatedCertInstallerTest extends BaseDeviceAdminTest {
 
     private static final String CERT_INSTALLER_PACKAGE = "com.android.cts.certinstaller";
 
@@ -163,12 +161,12 @@
         mReceivedException = null;
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_CERT_OPERATION_DONE);
-        getContext().registerReceiver(receiver, filter);
+        mContext.registerReceiver(receiver, filter);
     }
 
     @Override
     public void tearDown() throws Exception {
-        getContext().unregisterReceiver(receiver);
+        mContext.unregisterReceiver(receiver);
         mDpm.uninstallCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes());
         // Installed private key pair will be removed once the lockscreen password is cleared,
         // which is done in the hostside test.
@@ -246,7 +244,7 @@
         intent.setAction(ACTION_INSTALL_CERT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(intent);
+        mContext.startActivity(intent);
     }
 
     private void removeCaCert(byte[] cert) {
@@ -254,7 +252,7 @@
         intent.setAction(ACTION_REMOVE_CERT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(intent);
+        mContext.startActivity(intent);
     }
 
     private void verifyCaCert(byte[] cert) {
@@ -262,7 +260,7 @@
         intent.setAction(ACTION_VERIFY_CERT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(intent);
+        mContext.startActivity(intent);
     }
 
     private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
@@ -288,6 +286,6 @@
         intent.putExtra(EXTRA_KEY_DATA, key);
         intent.putExtra(EXTRA_KEY_ALIAS, alias);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getContext().startActivity(intent);
+        mContext.startActivity(intent);
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java
new file mode 100644
index 0000000..7fc0173
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+/**
+ * This test executes helper tasks as active device admin in the primary user. Current tasks are
+ * setting and clearing lockscreen password used by the host side delegated cert installer test.
+ */
+public class PrimaryUserAdminHelper extends AndroidTestCase {
+
+    private DevicePolicyManager mDpm;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+    }
+
+    /**
+     * Device admin can only be deactivated by itself and this test should be executed before the
+     * device admin package can be uninstalled.
+     */
+    public void testClearDeviceAdmin() throws Exception {
+        ComponentName cn = PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT;
+        if (mDpm.isAdminActive(cn)) {
+            mDpm.removeActiveAdmin(cn);
+            // Wait until device admin is not active (with 2 minutes timeout).
+            for (int i = 0; i < 2 * 60 && mDpm.isAdminActive(cn); i++) {
+                Thread.sleep(1000);  // 1 second.
+            }
+        }
+        assertFalse(mDpm.isAdminActive(cn));
+    }
+
+    /**
+     * Set lockscreen password.
+     */
+    public void testSetPassword() {
+        // Enable credential storage by setting a nonempty password.
+        assertTrue(mDpm.resetPassword("test", 0));
+    }
+
+    /**
+     * Clear lockscreen password.
+     */
+    public void testClearPassword() {
+        mDpm.setPasswordQuality(PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT,
+                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        mDpm.setPasswordMinimumLength(
+                PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT, 0);
+        assertTrue(mDpm.resetPassword("", 0));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java
new file mode 100644
index 0000000..f3c8ff6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.ComponentName;
+
+/**
+ * A device admin class running in the primary user. Currently used by delegated cert installer
+ * test to set a lockscreen password which is prerequisite of installKeyPair().
+ */
+public class PrimaryUserDeviceAdmin extends DeviceAdminReceiver {
+    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
+            PrimaryUserDeviceAdmin.class.getPackage().getName(),
+            PrimaryUserDeviceAdmin.class.getName());
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java
new file mode 100644
index 0000000..fed1a79
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Log;
+
+/**
+ * Simple activity that adds or clears a user restriction depending on the value of the extras.
+ */
+public class UserRestrictionActivity extends Activity {
+
+    private static final String TAG = UserRestrictionActivity.class.getName();
+
+    private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
+    private static final String EXTRA_COMMAND = "extra-command";
+
+    private static final String ADD_COMMAND = "add-restriction";
+    private static final String CLEAR_COMMAND = "clear-restriction";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        handleIntent(getIntent());
+    }
+
+    // Overriding this method in case another intent is sent to this activity before finish()
+    @Override
+    public void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        handleIntent(intent);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        // Calling finish() here because doing it in onCreate(), onStart() or onResume() makes
+        // "adb shell am start" timeout if using the -W option.
+        finish();
+    }
+
+    private void handleIntent(Intent intent) {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+        String command = intent.getStringExtra(EXTRA_COMMAND);
+        Log.i(TAG, "Command: \"" + command + "\". Restriction: \"" + restrictionKey + "\"");
+
+        if (ADD_COMMAND.equals(command)) {
+            dpm.addUserRestriction(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Added user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else if (CLEAR_COMMAND.equals(command)) {
+            dpm.clearUserRestriction(
+                    BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Cleared user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else {
+            Log.e(TAG, "Invalid command: " + command);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java
index 5cad040..f305e86 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java
@@ -61,7 +61,8 @@
             // Otherwise, we'll wait until we receive it.
             return;
         }
-        assertTrue(mPreferenceChanged.tryAcquire(40, TimeUnit.SECONDS));
+        // We're relying on background broadcast intents, which can take a long time.
+        assertTrue(mPreferenceChanged.tryAcquire(2, TimeUnit.MINUTES));
         assertTrue(mPreferences.getBoolean(
                 BroadcastIntentReceiver.OWNER_CHANGED_BROADCAST_RECEIVED_KEY, false));
     }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
index 0ec3d1e..4bac8a5 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
@@ -14,8 +14,6 @@
 -->
 <device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
     <uses-policies>
-         <reset-password />
-         <limit-password />
          <disable-camera />
     </uses-policies>
 </device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
index af0ac25..47f8716 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
@@ -21,8 +21,7 @@
 import android.test.AndroidTestCase;
 
 /**
- * This test executes helper tasks as active device admin in the primary user. Current tasks are
- * setting and clearing lockscreen password used by the host side delegated cert installer test.
+ * This test executes helper tasks as active device admin in the primary user.
  */
 public class PrimaryUserAdminHelper extends AndroidTestCase {
 
@@ -49,23 +48,4 @@
         }
         assertFalse(mDpm.isAdminActive(cn));
     }
-
-    /**
-     * Set lockscreen password.
-     */
-    public void testSetPassword() {
-        // Enable credential storage by setting a nonempty password.
-        assertTrue(mDpm.resetPassword("test", 0));
-    }
-
-    /**
-     * Clear lockscreen password.
-     */
-    public void testClearPassword() {
-        mDpm.setPasswordQuality(PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT,
-                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
-        mDpm.setPasswordMinimumLength(
-                PrimaryUserDeviceAdmin.ADMIN_RECEIVER_COMPONENT, 0);
-        assertTrue(mDpm.resetPassword("", 0));
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
new file mode 100644
index 0000000..e68c884
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsPackageInstallerApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml b/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml
new file mode 100644
index 0000000..aaa88f2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.packageinstaller">
+
+    <uses-sdk android:minSdkVersion="21"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <receiver
+            android:name=".ClearDeviceOwnerTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.packageinstaller"
+        android:label="Package Installer CTS Tests" />
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml
new file mode 100644
index 0000000..de4a9e1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml
@@ -0,0 +1,3 @@
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies />
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java
similarity index 70%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PackageInstallTest.java
rename to hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java
index 0eddbee..f994e9e 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PackageInstallTest.java
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java
@@ -13,17 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.cts.deviceowner;
+package com.android.cts.packageinstaller;
 
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
+
+import com.android.cts.packageinstaller.ClearDeviceOwnerTest.BasicAdminReceiver;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -31,34 +37,41 @@
 import java.io.OutputStream;
 
 /**
- * This class tests silent package install and uninstall by a device owner.
+ * Base test case for testing PackageInstaller.
  */
-public class PackageInstallTest extends BaseDeviceOwnerTest {
-    private static final String TEST_APP_LOCATION = "/data/local/tmp/CtsSimpleApp.apk";
-    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
-    private static final int PACKAGE_INSTALLER_TIMEOUT_MS = 60000; // 60 seconds
+public class BasePackageInstallTest extends InstrumentationTestCase {
+    protected static final String TEST_APP_LOCATION = "/data/local/tmp/CtsSimpleApp.apk";
+    protected static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    protected static final int PACKAGE_INSTALLER_TIMEOUT_MS = 60000; // 60 seconds
     private static final String ACTION_INSTALL_COMMIT =
             "com.android.cts.deviceowner.INTENT_PACKAGE_INSTALL_COMMIT";
-    private static final int PACKAGE_INSTALLER_STATUS_UNDEFINED = -1000;
+    protected static final int PACKAGE_INSTALLER_STATUS_UNDEFINED = -1000;
+    public static final String PACKAGE_NAME = SilentPackageInstallTest.class.getPackage().getName();
 
+    protected Context mContext;
+    protected UiDevice mDevice;
+    protected DevicePolicyManager mDevicePolicyManager;
     private PackageManager mPackageManager;
     private PackageInstaller mPackageInstaller;
     private PackageInstaller.Session mSession;
-    private boolean mCallbackReceived;
-    private int mCallbackStatus;
+    protected boolean mCallbackReceived;
+    protected int mCallbackStatus;
+    protected Intent mCallbackIntent;
 
-    private final Object mPackageInstallerTimeoutLock = new Object();
+    protected final Object mPackageInstallerTimeoutLock = new Object();
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            mContext.unregisterReceiver(this);
             synchronized (mPackageInstallerTimeoutLock) {
                 mCallbackStatus = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
                         PACKAGE_INSTALLER_STATUS_UNDEFINED);
                 if (mCallbackStatus == PackageInstaller.STATUS_SUCCESS) {
+                    mContext.unregisterReceiver(this);
                     assertEquals(TEST_APP_PKG, intent.getStringExtra(
                             PackageInstaller.EXTRA_PACKAGE_NAME));
+                } else if (mCallbackStatus == PackageInstaller.STATUS_PENDING_USER_ACTION) {
+                    mCallbackIntent = (Intent) intent.getExtras().get(Intent.EXTRA_INTENT);
                 }
                 mCallbackReceived = true;
                 mPackageInstallerTimeoutLock.notify();
@@ -69,6 +82,10 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mContext = getInstrumentation().getContext();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mPackageManager = mContext.getPackageManager();
         mPackageInstaller = mPackageManager.getPackageInstaller();
         assertNotNull(mPackageInstaller);
@@ -79,7 +96,10 @@
 
     @Override
     protected void tearDown() throws Exception {
-        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
+        if (mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME) ||
+                mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME)) {
+            mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
+        }
         try {
             mContext.unregisterReceiver(mBroadcastReceiver);
         } catch (IllegalArgumentException e) {
@@ -91,33 +111,12 @@
         super.tearDown();
     }
 
-    public void testSilentInstallUninstall() throws Exception {
-        // install the app
-        assertInstallPackage();
-
-        // uninstall the app again
-        assertTrue(tryUninstallPackage());
-        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    protected static ComponentName getWho() {
+        return new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
     }
 
-    public void testUninstallBlocked() throws Exception {
-        // install the app
-        assertInstallPackage();
-
-        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, true);
-        assertTrue(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
-        assertTrue(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
-        assertFalse(tryUninstallPackage());
-        assertTrue(isPackageInstalled(TEST_APP_PKG));
-
-        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
-        assertFalse(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
-        assertFalse(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
-        assertTrue(tryUninstallPackage());
+    protected void assertInstallPackage() throws Exception {
         assertFalse(isPackageInstalled(TEST_APP_PKG));
-    }
-
-    private void assertInstallPackage() throws Exception {
         synchronized (mPackageInstallerTimeoutLock) {
             mCallbackReceived = false;
             mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
@@ -134,7 +133,7 @@
         assertTrue(isPackageInstalled(TEST_APP_PKG));
     }
 
-    private boolean tryUninstallPackage() throws Exception {
+    protected boolean tryUninstallPackage() throws Exception {
         assertTrue(isPackageInstalled(TEST_APP_PKG));
         synchronized (mPackageInstallerTimeoutLock) {
             mCallbackReceived = false;
@@ -151,7 +150,7 @@
         }
     }
 
-    private void installPackage(String packageLocation) throws Exception {
+    protected void installPackage(String packageLocation) throws Exception {
         PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                 PackageInstaller.SessionParams.MODE_FULL_INSTALL);
         int sessionId = mPackageInstaller.createSession(params);
@@ -184,11 +183,11 @@
                 mContext,
                 sessionId,
                 broadcastIntent,
-                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
+                PendingIntent.FLAG_UPDATE_CURRENT);
         return pendingIntent.getIntentSender();
     }
 
-    private boolean isPackageInstalled(String packageName) {
+    protected boolean isPackageInstalled(String packageName) {
         try {
             PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
             return pi != null;
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
new file mode 100644
index 0000000..a06271b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.packageinstaller;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Base class for profile and device based tests.
+ *
+ * This class handles making sure that the test is the profile or device owner and that it has an
+ * active admin registered, so that all tests may assume these are done.
+ */
+public class ClearDeviceOwnerTest extends InstrumentationTestCase {
+
+    public static class BasicAdminReceiver extends DeviceAdminReceiver {
+    }
+
+    public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName();
+    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
+            PACKAGE_NAME, BasicAdminReceiver.class.getName());
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+                getInstrumentation().getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(mDevicePolicyManager);
+
+        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertTrue("App is not device owner", mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        removeActiveAdmin(ADMIN_RECEIVER_COMPONENT);
+        mDevicePolicyManager.clearDeviceOwnerApp(PACKAGE_NAME);
+        assertFalse(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertFalse(mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+
+        super.tearDown();
+    }
+
+    // This test clears the device owner and active admin on tearDown(). To be called from the host
+    // side test once a test case is finished.
+    public void testClearDeviceOwner() {
+    }
+
+    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
+        if (mDevicePolicyManager.isAdminActive(cn)) {
+            mDevicePolicyManager.removeActiveAdmin(cn);
+            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+                Thread.sleep(100);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
new file mode 100644
index 0000000..96affae
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.packageinstaller;
+
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+/**
+ * This class tests manual package install and uninstall by a device owner.
+ */
+public class ManualPackageInstallTest extends BasePackageInstallTest {
+    private static final int AUTOMATOR_WAIT_TIMEOUT = 5000;
+    private static final int INSTALL_WAIT_TIME = 5000;
+
+    private static final BySelector POPUP_BUTTON_SELECTOR = By
+            .clazz(android.widget.Button.class.getName())
+            .res("android:id/button1")
+            .pkg("com.google.android.packageinstaller");
+    private static final BySelector POPUP_TEXT_SELECTOR = By
+            .clazz(android.widget.TextView.class.getName())
+            .res("android:id/alertTitle")
+            .pkg("com.google.android.packageinstaller");
+    private static final BySelector INSTALL_BUTTON_SELECTOR = By
+            .clazz(android.widget.Button.class.getName())
+            .res("com.android.packageinstaller:id/ok_button")
+            .pkg("com.google.android.packageinstaller");
+
+    public void testManualInstallSucceeded() throws Exception {
+        assertInstallPackage();
+    }
+
+    public void testManualInstallBlocked() throws Exception {
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+        // Calls the original installPackage which does not click through the install button.
+        super.installPackage(TEST_APP_LOCATION);
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
+        }
+
+        mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(mCallbackIntent);
+
+        automateDismissInstallBlockedDialog();
+
+        // Assuming installation is not synchronous, we should wait a while before checking.
+        Thread.sleep(INSTALL_WAIT_TIME);
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    @Override
+    protected void installPackage(String packageLocation) throws Exception {
+        super.installPackage(packageLocation);
+
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
+        }
+
+        // Use a receiver to listen for package install.
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+
+        mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(mCallbackIntent);
+
+        automateInstallClick();
+    }
+
+    private void automateInstallClick() {
+        mDevice.wait(Until.hasObject(INSTALL_BUTTON_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
+        UiObject2 button = mDevice.findObject(INSTALL_BUTTON_SELECTOR);
+        assertNotNull("Install button not found", button);
+        button.click();
+    }
+
+    private void automateDismissInstallBlockedDialog() {
+        mDevice.wait(Until.hasObject(POPUP_TEXT_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
+        UiObject2 text = mDevice.findObject(POPUP_TEXT_SELECTOR);
+        assertNotNull("Alert dialog not found", text);
+        // "OK" button only present in the dialog if it is blocked by policy.
+        UiObject2 button = mDevice.findObject(POPUP_BUTTON_SELECTOR);
+        assertNotNull("OK button not found", button);
+        button.click();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.java
new file mode 100644
index 0000000..f1a80b9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.packageinstaller;
+
+/**
+ * This class tests silent package install and uninstall by a device owner.
+ */
+public class SilentPackageInstallTest extends BasePackageInstallTest {
+    public void testSilentInstallUninstall() throws Exception {
+        // install the app
+        assertInstallPackage();
+
+        // uninstall the app again
+        assertTrue(tryUninstallPackage());
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    public void testUninstallBlocked() throws Exception {
+        // install the app
+        assertInstallPackage();
+
+        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, true);
+        assertTrue(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
+        assertTrue(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
+        assertFalse(tryUninstallPackage());
+        assertTrue(isPackageInstalled(TEST_APP_PKG));
+
+        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
+        assertFalse(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
+        assertFalse(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
+        assertTrue(tryUninstallPackage());
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 650e963..4fc14e4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -17,7 +17,6 @@
 package com.android.cts.devicepolicy;
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.InstrumentationResultParser;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
@@ -363,4 +362,20 @@
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
         return commandOutput.startsWith("Success:");
     }
+
+    protected String getSettings(String namespace, String name, int userId)
+            throws DeviceNotAvailableException {
+        String command = "settings --user " + userId + " get " + namespace + " " + name;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        return commandOutput.replace("\n", "").replace("\r", "");
+    }
+
+    protected void putSettings(String namespace, String name, String value, int userId)
+            throws DeviceNotAvailableException {
+        String command = "settings --user " + userId + " put " + namespace + " " + name
+                + " " + value;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
index 7cb8f3b..8d22638 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
@@ -16,9 +16,7 @@
 
 package com.android.cts.devicepolicy;
 
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.log.LogUtil.CLog;
-
+import java.io.File;
 import java.lang.Exception;
 
 /**
@@ -49,6 +47,18 @@
     private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    private static final String TEST_APP_LOCATION = "/data/local/tmp/";
+
+    private static final String PACKAGE_INSTALLER_PKG = "com.android.cts.packageinstaller";
+    private static final String PACKAGE_INSTALLER_APK = "CtsPackageInstallerApp.apk";
+    private static final String PACKAGE_INSTALLER_ADMIN_COMPONENT =
+            PACKAGE_INSTALLER_PKG + "/" + ".ClearDeviceOwnerTest$BasicAdminReceiver";
+    private static final String PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS =
+            PACKAGE_INSTALLER_PKG + ".ClearDeviceOwnerTest";
+
+    @Override
     public void tearDown() throws Exception {
         if (mHasFeature) {
             getDevice().uninstallPackage(DEVICE_OWNER_PKG);
@@ -117,4 +127,28 @@
                     "testRemoveAccounts", 0));
         }
     }
+
+    public void testSilentPackageInstall() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
+        try {
+            // Install the test and prepare the test apk.
+            installApp(PACKAGE_INSTALLER_APK);
+            assertTrue(setDeviceOwner(PACKAGE_INSTALLER_ADMIN_COMPONENT));
+
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
+            assertTrue(runDeviceTests(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_PKG + ".SilentPackageInstallTest"));
+        } finally {
+            assertTrue("Failed to remove device owner.", runDeviceTests(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS));
+            String command = "rm " + TEST_APP_LOCATION + apk.getName();
+            String commandOutput = getDevice().executeShellCommand(command);
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            getDevice().uninstallPackage(PACKAGE_INSTALLER_PKG);
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 36dab2c..43e6730 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -16,6 +16,12 @@
 
 package com.android.cts.devicepolicy;
 
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.io.File;
+
 /**
  * Set of tests for usecases that apply to profile and device owner.
  * This class is the base class of MixedProfileOwnerTest and MixedDeviceOwnerTest and is abstract
@@ -34,8 +40,21 @@
     private static final String SIMPLE_PRE_M_APP_PKG = "com.android.cts.launcherapps.simplepremapp";
     private static final String SIMPLE_PRE_M_APP_APK = "CtsSimplePreMApp.apk";
 
+    private static final String CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
+    private static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
+
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    private static final String TEST_APP_LOCATION = "/data/local/tmp/";
+
+    private static final String PACKAGE_INSTALLER_PKG = "com.android.cts.packageinstaller";
+    private static final String PACKAGE_INSTALLER_APK = "CtsPackageInstallerApp.apk";
+
     protected static final int USER_OWNER = 0;
 
+    private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
+    private static final String CLEAR_RESTRICTION_COMMAND = "clear-restriction";
+
     // ID of the user all tests are run as. For device owner this will be 0, for profile owner it
     // is the user id of the created profile.
     protected int mUserId;
@@ -46,6 +65,7 @@
             getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
             getDevice().uninstallPackage(PERMISSIONS_APP_PKG);
             getDevice().uninstallPackage(SIMPLE_PRE_M_APP_PKG);
+            getDevice().uninstallPackage(CERT_INSTALLER_PKG);
         }
         super.tearDown();
     }
@@ -159,13 +179,85 @@
         executeDeviceTestClass(".ApplicationHiddenTest");
     }
 
-    // TODO: Remove AccountManagementTest from XTS after GTS is released for MNC.
     public void testAccountManagement() throws Exception {
         if (!mHasFeature) {
             return;
         }
 
         executeDeviceTestClass(".AccountManagementTest");
+
+        // Send a home intent to dismiss an error dialog.
+        String command = "am start -a android.intent.action.MAIN -c android.intent.category.HOME";
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+                + getDevice().executeShellCommand(command));
+    }
+
+    public void testDelegatedCertInstaller() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(CERT_INSTALLER_APK, mUserId);
+        installAppAsUser(DEVICE_ADMIN_APK, USER_OWNER);
+        setDeviceAdmin(DEVICE_ADMIN_PKG + "/.PrimaryUserDeviceAdmin");
+
+        final String adminHelperClass = ".PrimaryUserAdminHelper";
+        try {
+            // Set a non-empty device lockscreen password, which is a precondition for installing
+            // private key pairs.
+            assertTrue("Set lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                    adminHelperClass, "testSetPassword", 0 /* user 0 */));
+            assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                    ".DelegatedCertInstallerTest", mUserId));
+        } finally {
+            // Reset lockscreen password and remove device admin.
+            assertTrue("Clear lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                    adminHelperClass, "testClearPassword", 0 /* user 0 */));
+            assertTrue("Clear device admin failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                    adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
+        }
+    }
+
+    public void testPackageInstallUserRestrictions() throws Exception {
+        // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES
+        final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
+        final String UNKNOWN_SOURCES_SETTING = "install_non_market_apps";
+        final String SECURE_SETTING_CATEGORY = "secure";
+        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
+        String unknownSourceSetting = null;
+        try {
+            // Install the test and prepare the test apk.
+            installApp(PACKAGE_INSTALLER_APK);
+            assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
+
+            // Add restrictions and test if we can install the apk.
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            changeUserRestrictionForUser(DISALLOW_INSTALL_UNKNOWN_SOURCES,
+                    ADD_RESTRICTION_COMMAND, mUserId);
+            assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG, ".ManualPackageInstallTest",
+                    "testManualInstallBlocked", mUserId));
+
+            // Clear restrictions and test if we can install the apk.
+            changeUserRestrictionForUser(DISALLOW_INSTALL_UNKNOWN_SOURCES,
+                    CLEAR_RESTRICTION_COMMAND, mUserId);
+
+            // Enable Unknown sources in Settings.
+            unknownSourceSetting =
+                    getSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, mUserId);
+            putSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, "1", mUserId);
+            assertEquals("1",
+                    getSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, mUserId));
+            assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG, ".ManualPackageInstallTest",
+                    "testManualInstallSucceeded", mUserId));
+        } finally {
+            String command = "rm " + TEST_APP_LOCATION + apk.getName();
+            getDevice().executeShellCommand(command);
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            getDevice().uninstallPackage(PACKAGE_INSTALLER_APK);
+            if (unknownSourceSetting != null) {
+                putSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, unknownSourceSetting,
+                        mUserId);
+            }
+        }
     }
 
     protected void executeDeviceTestClass(String className) throws Exception {
@@ -175,4 +267,18 @@
     protected void executeDeviceTestMethod(String className, String testName) throws Exception {
         assertTrue(runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId));
     }
+
+    private void changeUserRestrictionForUser(String key, String command, int userId)
+            throws DeviceNotAvailableException {
+        String adbCommand = "am start -W --user " + userId
+                + " -c android.intent.category.DEFAULT "
+                + " --es extra-command " + command
+                + " --es extra-restriction-key " + key
+                + " " + DEVICE_ADMIN_PKG + "/.UserRestrictionActivity";
+        String commandOutput = getDevice().executeShellCommand(adbCommand);
+        CLog.logAndDisplay(LogLevel.INFO,
+                "Output for command " + adbCommand + ": " + commandOutput);
+        assertTrue("Command was expected to succeed " + commandOutput,
+                commandOutput.contains("Status: ok"));
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 4f267d1..96ca469 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -16,12 +16,6 @@
 
 package com.android.cts.devicepolicy;
 
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.io.File;
-
 /**
  * Set of tests for Device Owner use cases.
  */
@@ -35,10 +29,6 @@
     private static final String MANAGED_PROFILE_ADMIN =
             MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
 
-    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
-    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
-    private static final String TEST_APP_LOCATION = "/data/local/tmp/";
-
     private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
@@ -93,19 +83,6 @@
         }
     }
 
-    public void testPackageInstall() throws Exception {
-        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
-        try {
-            getDevice().uninstallPackage(TEST_APP_PKG);
-            assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
-            executeDeviceOwnerTest("PackageInstallTest");
-        } finally {
-            String command = "rm " + TEST_APP_LOCATION + apk.getName();
-            String commandOutput = getDevice().executeShellCommand(command);
-            getDevice().uninstallPackage(TEST_APP_PKG);
-        }
-    }
-
     public void testSystemUpdatePolicy() throws Exception {
         executeDeviceOwnerTest("SystemUpdatePolicyTest");
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index acc5b26..214131f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -42,9 +42,6 @@
     private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
-    private static final String CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
-    private static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
-
     private static final String WIFI_CONFIG_CREATOR_PKG = "com.android.cts.wificonfigcreator";
     private static final String WIFI_CONFIG_CREATOR_APK = "CtsWifiConfigCreator.apk";
 
@@ -94,7 +91,6 @@
             getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
             getDevice().uninstallPackage(INTENT_SENDER_PKG);
             getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
-            getDevice().uninstallPackage(CERT_INSTALLER_PKG);
         }
         super.tearDown();
     }
@@ -525,28 +521,6 @@
                 "testSetBluetoothContactSharingDisabled_setterAndGetter", mUserId));
     }
 
-    public void testDelegatedCertInstaller() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        installApp(CERT_INSTALLER_APK);
-        setDeviceAdmin(MANAGED_PROFILE_PKG + "/.PrimaryUserDeviceAdmin");
-
-        final String adminHelperClass = ".PrimaryUserAdminHelper";
-        try {
-            assertTrue("Set lockscreen password failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                    adminHelperClass, "testSetPassword", 0 /* user 0 */));
-            assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                    ".DelegatedCertInstallerTest", mUserId));
-        } finally {
-            // Reset lockscreen password and remove device admin.
-            assertTrue("Clear lockscreen password failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                    adminHelperClass, "testClearPassword", 0 /* user 0 */));
-            assertTrue("Clear device admin failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
-                    adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
-        }
-    }
-
     public void testCannotSetProfileOwnerAgain() throws Exception {
         if (!mHasFeature) {
             return;
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 754e38a..f8ea45f 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,5 +1,14 @@
 [
 {
+  description: "some AlarmClockTests are not robust across different device types",
+  names: [
+    "android.alarmclock.cts.DismissAlarmTest#testAll",
+    "android.alarmclock.cts.SetAlarmTest#testAll",
+    "android.alarmclock.cts.SnoozeAlarmTest#testAll"
+  ],
+  bug: 23776083
+},
+{
   description: "the UsageStats is not yet stable enough",
   names: [
     "android.app.usage.cts.UsageStatsTest"
@@ -15,6 +24,21 @@
   bug: 17595050
 },
 {
+  description: "test fails on devices with no telephony",
+  names: [
+    "android.calllog.cts.CallLogBackupTest#testSingleCallBackup"
+  ],
+  bug: 23776099
+},
+{
+  description: "test fails on some devices",
+  names: [
+    "android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput",
+    "android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats"
+  ],
+  bug: 23776893
+},
+{
   description: "the SSLCertificateSocketFactoryTest often fails because of lack of live internet or short timeout, it should be refactored to do a local server testing",
   names: [
     "android.net.cts.SSLCertificateSocketFactoryTest#testCreateSocket",
@@ -39,6 +63,21 @@
   bug: 18461670
 },
 {
+  description: "test not robust",
+  names: [
+    "android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect",
+    "android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections"
+  ],
+  bug: 23604254
+},
+{
+  description: "tests too flaky",
+  names: [
+    "android.transition.cts.ChangeScrollTest#testChangeScroll"
+  ],
+  bug: 23779020
+},
+{
   description: "Not all jdwp features are currently supported. These tests will fail",
   names: [
     "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001",
@@ -119,6 +158,21 @@
   bug: 17508787
 },
 {
+  description: "This test should be outside of official CTS suite until it is verified for all Nexus devices",
+  names: [
+    "com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPackageInstallUserRestrictions",
+    "com.android.cts.devicepolicy.MixedProfileOwnerTest#testPackageInstallUserRestrictions"
+  ],
+  bug: 18928535
+},
+{
+  description: "Test is not yet properly implemented",
+  names: [
+    "android.voicesettings.cts.ZenModeTest#testAll"
+  ],
+  bug: 23238984
+},
+{
   description: "These tests fail on some devices.",
   names: [
     "android.uirendering.cts.testclasses.ExactCanvasTests#testBlueRect",
@@ -234,5 +288,12 @@
     "android.hardware.cts.SingleSensorTests#testOrientation_5hz"
   ],
   bug: 22922206
+},
+{
+  description: "tests are not yet ready",
+  names: [
+    "com.android.cts.app.os.OsHostTests#testNonExportedActivities"
+  ],
+  bug: 23779168
 }
 ]
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index 71bf6cf..ca20549 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -24,8 +24,10 @@
 import android.app.Service;
 import android.app.UiAutomation;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Button;
 import android.widget.EditText;
@@ -44,6 +46,8 @@
 public class AccessibilityEndToEndTest extends
         AccessibilityActivityTestCase<AccessibilityEndToEndActivity> {
 
+    private static final String LOG_TAG = "AccessibilityEndToEndTest";
+
     /**
      * Creates a new instance for testing {@link AccessibilityEndToEndActivity}.
      */
@@ -309,6 +313,14 @@
     @MediumTest
     @SuppressWarnings("deprecation")
     public void testTypeNotificationStateChangedAccessibilityEvent() throws Throwable {
+        // No notification UI on televisions.
+        if((getActivity().getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
+            Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" +
+                    " - No notification UI on televisions.");
+            return;
+        }
+
         String message = getActivity().getString(R.string.notification_message);
 
         // create the notification to send
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
index a79df42..cc444a6 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -249,7 +249,9 @@
 
         @Override
         public void onBatchScanResults(List<ScanResult> results) {
-            mBatchScanResults = results;
+            // In case onBatchScanResults are called due to buffer full, we want to collect all
+            // scan results.
+            mBatchScanResults.addAll(results);
         }
 
         // Clear regular and batch scan results.
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 0e7eb43..9e75d94 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -107,6 +107,12 @@
     private final int INDEX_ALGORITHM_AWB = 1;
     private final int INDEX_ALGORITHM_AF = 2;
 
+    private enum TorchSeqState {
+        RAMPING_UP,
+        FIRED,
+        RAMPING_DOWN
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -963,16 +969,39 @@
         waitForNumResults(listener, flashModeTorchRequests - NUM_FLASH_REQUESTS_TESTED);
 
         // Verify the results
+        TorchSeqState state = TorchSeqState.RAMPING_UP;
         for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) {
             result = listener.getCaptureResultForRequest(torchRequest,
                     NUM_RESULTS_WAIT_TIMEOUT);
-
-            // Result mode must be TORCH, state must be FIRED
-            mCollector.expectEquals("Flash mode result must be TORCH",
+            int flashMode = result.get(CaptureResult.FLASH_MODE);
+            int flashState = result.get(CaptureResult.FLASH_STATE);
+            // Result mode must be TORCH
+            mCollector.expectEquals("Flash mode result " + i + " must be TORCH",
                     CaptureResult.FLASH_MODE_TORCH, result.get(CaptureResult.FLASH_MODE));
-            mCollector.expectEquals("Flash state result must be FIRED",
-                    CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
+            if (state == TorchSeqState.RAMPING_UP &&
+                    flashState == CaptureResult.FLASH_STATE_FIRED) {
+                state = TorchSeqState.FIRED;
+            } else if (state == TorchSeqState.FIRED &&
+                    flashState == CaptureResult.FLASH_STATE_PARTIAL) {
+                state = TorchSeqState.RAMPING_DOWN;
+            }
+
+            if (i == 0 && mStaticInfo.isPerFrameControlSupported()) {
+                mCollector.expectTrue(
+                        "Per frame control device must enter FIRED state on first torch request",
+                        state == TorchSeqState.FIRED);
+            }
+
+            if (state == TorchSeqState.FIRED) {
+                mCollector.expectEquals("Flash state result " + i + " must be FIRED",
+                        CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
+            } else {
+                mCollector.expectEquals("Flash state result " + i + " must be PARTIAL",
+                        CaptureResult.FLASH_STATE_PARTIAL, result.get(CaptureResult.FLASH_STATE));
+            }
         }
+        mCollector.expectTrue("Torch state FIRED never seen",
+                state == TorchSeqState.FIRED || state == TorchSeqState.RAMPING_DOWN);
 
         // Test flash OFF mode control
         requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 9f85fd8..52fd69f 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -375,7 +375,7 @@
                     prepareRecording(size, videoFramerate, captureRate);
 
                     // prepare preview surface by using video size.
-                    updatePreviewSurfaceWithVideoSize(size);
+                    updatePreviewSurfaceWithVideo(size, captureRate);
 
                     // Start recording
                     SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -440,7 +440,7 @@
                         prepareRecording(size, VIDEO_FRAME_RATE, captureRate);
 
                         // prepare preview surface by using video size.
-                        updatePreviewSurfaceWithVideoSize(size);
+                        updatePreviewSurfaceWithVideo(size, captureRate);
 
                         // Start recording
                         SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -631,7 +631,7 @@
             prepareRecordingWithProfile(profile);
 
             // prepare preview surface by using video size.
-            updatePreviewSurfaceWithVideoSize(videoSz);
+            updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
 
             // Start recording
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -681,7 +681,7 @@
             prepareRecording(sz, VIDEO_FRAME_RATE, VIDEO_FRAME_RATE);
 
             // prepare preview surface by using video size.
-            updatePreviewSurfaceWithVideoSize(sz);
+            updatePreviewSurfaceWithVideo(sz, VIDEO_FRAME_RATE);
 
             // Start recording
             SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
@@ -901,7 +901,7 @@
                                 CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
 
                 // prepare preview surface by using video size.
-                updatePreviewSurfaceWithVideoSize(videoSz);
+                updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
 
                 prepareVideoSnapshot(videoSnapshotRequestBuilder, imageListener);
                 CaptureRequest request = videoSnapshotRequestBuilder.build();
@@ -1001,20 +1001,44 @@
      * <p>Preview size will be capped with max preview size.</p>
      *
      * @param videoSize The video size used for preview.
+     * @param videoFrameRate The video frame rate
+     *
      */
-    private void updatePreviewSurfaceWithVideoSize(Size videoSize) {
+    private void updatePreviewSurfaceWithVideo(Size videoSize, int videoFrameRate) {
         if (mOrderedPreviewSizes == null) {
             throw new IllegalStateException("supported preview size list is not initialized yet");
         }
+        final float FRAME_DURATION_TOLERANCE = 0.01f;
+        long videoFrameDuration = (long) (1e9 / videoFrameRate *
+                (1.0 + FRAME_DURATION_TOLERANCE));
+        HashMap<Size, Long> minFrameDurationMap = mStaticInfo.
+                getAvailableMinFrameDurationsForFormatChecked(ImageFormat.PRIVATE);
         Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        Size previewSize = videoSize;
+        Size previewSize = null;
         if (videoSize.getWidth() > maxPreviewSize.getWidth() ||
                 videoSize.getHeight() > maxPreviewSize.getHeight()) {
-            Log.w(TAG, "Overwrite preview size from " + videoSize.toString() +
-                    " to " + maxPreviewSize.toString());
-            previewSize = maxPreviewSize;
+            for (Size s : mOrderedPreviewSizes) {
+                Long frameDuration = minFrameDurationMap.get(s);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    // Legacy doesn't report min frame duration
+                    frameDuration = new Long(0);
+                }
+                assertTrue("Cannot find minimum frame duration for private size" + s,
+                        frameDuration != null);
+                if (frameDuration <= videoFrameDuration &&
+                        s.getWidth() <= videoSize.getWidth() &&
+                        s.getHeight() <= videoSize.getHeight()) {
+                    Log.w(TAG, "Overwrite preview size from " + videoSize.toString() +
+                            " to " + s.toString());
+                    previewSize = s;
+                    break;
+                    // If all preview size doesn't work then we fallback to video size
+                }
+            }
         }
-
+        if (previewSize == null) {
+            previewSize = videoSize;
+        }
         updatePreviewSurface(previewSize);
     }
 
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
index 4750b09..c807e03 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
@@ -35,21 +35,21 @@
  */
 public class SensorParameterRangeTest extends SensorTestCase {
 
-    private static final double ACCELEROMETER_MAX_RANGE = 8 * 9.81; // 8G
-    private static final int ACCELEROMETER_MIN_FREQUENCY = 5;
+    private static final double ACCELEROMETER_MAX_RANGE = 8 * 9.80; // 8G minus a slop
+    private static final double ACCELEROMETER_MIN_FREQUENCY = 12.50;
     private static final int ACCELEROMETER_MAX_FREQUENCY = 200;
 
-    private static final double GYRO_MAX_RANGE = 1000/57.295; // 1000 degrees per sec.
-    private static final int GYRO_MIN_FREQUENCY = 5;
-    private static final int GYRO_MAX_FREQUENCY = 200;
+    private static final double GYRO_MAX_RANGE = 1000/57.295 - 1.0; // 1000 degrees per sec minus a slop
+    private static final double GYRO_MIN_FREQUENCY = 12.50;
+    private static final double GYRO_MAX_FREQUENCY = 200.0;
 
     private static final int MAGNETOMETER_MAX_RANGE = 900;   // micro telsa
-    private static final int MAGNETOMETER_MIN_FREQUENCY = 5;
-    private static final int MAGNETOMETER_MAX_FREQUENCY = 50;
+    private static final double MAGNETOMETER_MIN_FREQUENCY = 5.0;
+    private static final double MAGNETOMETER_MAX_FREQUENCY = 50.0;
 
-    private static final int PRESSURE_MAX_RANGE = 1100;     // hecto-pascal
-    private static final int PRESSURE_MIN_FREQUENCY = 1;
-    private static final int PRESSURE_MAX_FREQUENCY = 10;
+    private static final double PRESSURE_MAX_RANGE = 1100.0;     // hecto-pascal
+    private static final double PRESSURE_MIN_FREQUENCY = 1.0;
+    private static final double PRESSURE_MAX_FREQUENCY = 10.0;
 
     private boolean mHasHifiSensors;
     private SensorManager mSensorManager;
@@ -94,7 +94,7 @@
     }
 
     private void checkSensorRangeAndFrequency(
-          Sensor sensor, double maxRange, int minFrequency, int maxFrequency) {
+          Sensor sensor, double maxRange, double minFrequency, double maxFrequency) {
         if (!mHasHifiSensors) return;
         assertTrue(String.format("%s Range actual=%.2f expected=%.2f %s",
                     sensor.getName(), sensor.getMaximumRange(), maxRange,
@@ -104,12 +104,12 @@
                 TimeUnit.MICROSECONDS);
         assertTrue(String.format("%s Min Frequency actual=%.2f expected=%dHz",
                     sensor.getName(), actualMinFrequency, minFrequency), actualMinFrequency <=
-                minFrequency);
+                minFrequency + 0.1);
 
         double actualMaxFrequency = SensorCtsHelper.getFrequency(sensor.getMinDelay(),
                 TimeUnit.MICROSECONDS);
         assertTrue(String.format("%s Max Frequency actual=%.2f expected=%dHz",
                     sensor.getName(), actualMaxFrequency, maxFrequency), actualMaxFrequency >=
-                maxFrequency);
+                maxFrequency - 0.1);
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
index 6156d3d..47c8313 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
@@ -223,7 +223,7 @@
         if (mSamplingPeriodUs == SensorManager.SENSOR_DELAY_FASTEST) {
             return "fastest";
         }
-        return String.format("%.0fhz", getFrequencyHz());
+        return String.format("%.2fhz", getFrequencyHz());
     }
 
     /**
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
index cf34f28..2f4777b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
@@ -128,9 +128,9 @@
         stats.addValue(SensorStats.FREQUENCY_KEY, measuredFrequencyHz);
         stats.addValue(PASSED_KEY, !failed);
         String resultString = String.format(
-                "Requested \"%s\" at %.2fHz (expecting between %.2fHz and %.2fHz, measured %.2fHz)",
+                "Requested \"%s\" at %s (expecting between %.2fHz and %.2fHz, measured %.2fHz)",
                 environment.getSensor().getName(),
-                environment.getFrequencyHz(),
+                environment.getFrequencyString(),
                 mLowerThresholdHz,
                 mUpperThresholdHz,
                 measuredFrequencyHz);
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
index 1e1c950..1b66e6a 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
@@ -24,8 +24,10 @@
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.TestSensorEvent;
+import android.hardware.cts.helpers.SensorCtsHelper;
 import android.util.Log;
 
+import java.util.concurrent.TimeUnit;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -66,18 +68,37 @@
      */
     public static StandardDeviationVerification getDefault(TestSensorEnvironment environment) {
         int sensorType = environment.getSensor().getType();
-        float mGraceFactorAccelGyro = 2.0f;
-        float mGraceFactorMagPressure = 4.0f;
-        float mMaxBandWidth = (float) environment.getFrequencyHz();
-        float mAccelNoise = (float)(mGraceFactorAccelGyro * Math.sqrt(mMaxBandWidth) * (9.81 * 0.0004));
-        float mGyroNoise = (float)(mGraceFactorAccelGyro * Math.sqrt(mMaxBandWidth) * (Math.PI/180.0 * 0.014));
-        float mMagNoise = (float)((mGraceFactorMagPressure) * 0.5); // Allow extra grace for mag
-        float mPressureNoise = (float)(mGraceFactorMagPressure * 0.02 * (float)Math.sqrt(mMaxBandWidth)); // Allow extra grace for pressure
+        float graceFactorAccelGyro = 2.0f;
+        float graceFactorMagPressure = 4.0f;
+        float currOperatingFreq = (float) environment.getFrequencyHz();
+        float maxBandWidth = (float)SensorCtsHelper.getFrequency(
+                environment.getSensor().getMinDelay(), TimeUnit.MICROSECONDS);
+        float minBandWidth = (float) SensorCtsHelper.getFrequency(
+                environment.getSensor().getMaxDelay(), TimeUnit.MICROSECONDS);
+
+        if (Float.isInfinite(currOperatingFreq)) {
+            currOperatingFreq = maxBandWidth;
+        }
+
+        if (currOperatingFreq > maxBandWidth && !Float.isInfinite(maxBandWidth)) {
+            currOperatingFreq = maxBandWidth;
+        }
+
+        if (currOperatingFreq < minBandWidth && !Float.isInfinite(minBandWidth)) {
+            currOperatingFreq = minBandWidth;
+        }
+
+        float mAccelNoise = (float)(graceFactorAccelGyro * Math.sqrt(currOperatingFreq) *
+                (9.81 * 0.0004));
+        float mGyroNoise = (float)(graceFactorAccelGyro * Math.sqrt(currOperatingFreq) *
+                (Math.PI/180.0 * 0.014));
+        float mMagNoise = (float)((graceFactorMagPressure) * 0.5); // Allow extra grace for mag
+        float mPressureNoise = (float)(graceFactorMagPressure * 0.02 *
+                (float)Math.sqrt(currOperatingFreq)); // Allow extra grace for pressure
 
         if (!DEFAULTS.containsKey(sensorType)) {
             return null;
         }
-
         boolean hasHifiSensors = environment.getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_HIFI_SENSORS);
 
@@ -132,9 +153,9 @@
             if (stdDevs[i] > mThreshold[i]) {
                 failed = true;
             }
-            stddevSb.append(String.format("%.3f", stdDevs[i]));
+            stddevSb.append(String.format("%.6f", stdDevs[i]));
             if (i != stdDevs.length - 1) stddevSb.append(", ");
-            expectedSb.append(String.format("<%.3f", mThreshold[i]));
+            expectedSb.append(String.format("<%.6f", mThreshold[i]));
             if (i != stdDevs.length - 1) expectedSb.append(", ");
         }
         if (stdDevs.length > 1) {
diff --git a/tests/tests/media/res/raw/test1m1shighstereo.mp3 b/tests/tests/media/res/raw/test1m1shighstereo.mp3
new file mode 100644
index 0000000..2a97077
--- /dev/null
+++ b/tests/tests/media/res/raw/test1m1shighstereo.mp3
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index d5b2907..f844b76 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -1434,6 +1434,42 @@
         return 1;
     }
 
+    public void testPositionAtEnd() throws Throwable {
+        testPositionAtEnd(R.raw.test1m1shighstereo);
+        testPositionAtEnd(R.raw.loudsoftmp3);
+        testPositionAtEnd(R.raw.loudsoftmp3);
+        testPositionAtEnd(R.raw.loudsoftwav);
+        testPositionAtEnd(R.raw.loudsoftogg);
+        testPositionAtEnd(R.raw.loudsoftitunes);
+        testPositionAtEnd(R.raw.loudsoftfaac);
+        testPositionAtEnd(R.raw.loudsoftaac);
+    }
+
+    private void testPositionAtEnd(int res) throws Throwable {
+
+        loadResource(res);
+        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+        mMediaPlayer.prepare();
+        int duration = mMediaPlayer.getDuration();
+        assertTrue("resource too short", duration > 6000);
+        mOnCompletionCalled.reset();
+        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(MediaPlayer mp) {
+                mOnCompletionCalled.signal();
+            }
+        });
+        mMediaPlayer.seekTo(duration - 5000);
+        mMediaPlayer.start();
+        while (mMediaPlayer.isPlaying()) {
+            Log.i("@@@@", "position: " + mMediaPlayer.getCurrentPosition());
+            Thread.sleep(500);
+        }
+        Log.i("@@@@", "final position: " + mMediaPlayer.getCurrentPosition());
+        assertTrue(mMediaPlayer.getCurrentPosition() > duration - 1000);
+        mMediaPlayer.reset();
+    }
+
     public void testCallback() throws Throwable {
         final int mp4Duration = 8484;
 
diff --git a/tests/tests/netlegacy22/Android.mk b/tests/tests/netlegacy22/Android.mk
index 68fd6f8..3174652 100644
--- a/tests/tests/netlegacy22/Android.mk
+++ b/tests/tests/netlegacy22/Android.mk
@@ -12,21 +12,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsNetTestCasesLegacyApi22
-
-LOCAL_SDK_VERSION := 22
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-include $(BUILD_CTS_PACKAGE)
+# Build the API tests and the permissions tests using their own makefiles.
+include $(call all-subdir-makefiles)
diff --git a/tests/tests/netlegacy22/api/Android.mk b/tests/tests/netlegacy22/api/Android.mk
new file mode 100644
index 0000000..68fd6f8
--- /dev/null
+++ b/tests/tests/netlegacy22/api/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsNetTestCasesLegacyApi22
+
+LOCAL_SDK_VERSION := 22
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netlegacy22/AndroidManifest.xml b/tests/tests/netlegacy22/api/AndroidManifest.xml
similarity index 100%
rename from tests/tests/netlegacy22/AndroidManifest.xml
rename to tests/tests/netlegacy22/api/AndroidManifest.xml
diff --git a/tests/tests/netlegacy22/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java b/tests/tests/netlegacy22/api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
similarity index 100%
rename from tests/tests/netlegacy22/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
rename to tests/tests/netlegacy22/api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
diff --git a/tests/tests/netlegacy22/permission/Android.mk b/tests/tests/netlegacy22/permission/Android.mk
new file mode 100644
index 0000000..fff9d85
--- /dev/null
+++ b/tests/tests/netlegacy22/permission/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsNetTestCasesLegacyPermission22
+
+LOCAL_SDK_VERSION := 22
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netlegacy22/permission/AndroidManifest.xml b/tests/tests/netlegacy22/permission/AndroidManifest.xml
new file mode 100644
index 0000000..d407404
--- /dev/null
+++ b/tests/tests/netlegacy22/permission/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.permission">
+
+    <uses-permission android:name="android.permission.INJECT_EVENTS" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.permission.cts.PermissionStubActivity"
+                  android:label="PermissionStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <!--
+        The CTS stubs package cannot be used as the target application here,
+        since that requires many permissions to be set. Instead, specify this
+        package itself as the target and include any stub activities needed.
+
+        This test package uses the default InstrumentationTestRunner, because
+        the InstrumentationCtsTestRunner is only available in the stubs
+        package. That runner cannot be added to this package either, since it
+        relies on hidden APIs.
+    -->
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.permission"
+                     android:label="CTS tests of com.android.cts.permission">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java b/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java
new file mode 100644
index 0000000..0e59288
--- /dev/null
+++ b/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts.legacy.api22.permission;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+* Test that protected android.net.ConnectivityManager methods cannot be called without
+* permissions
+*/
+public class ConnectivityManagerPermissionTest extends AndroidTestCase {
+
+    private ConnectivityManager mConnectivityManager = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        assertNotNull(mConnectivityManager);
+    }
+
+    /**
+     * Verify that calling {@link ConnectivityManager#requestRouteToHost(int, int)}
+     * requires permissions.
+     * <p>Tests Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testRequestRouteToHost() {
+        try {
+            mConnectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE, 1);
+            fail("Was able to call requestRouteToHost");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+}
diff --git a/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java b/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java
new file mode 100644
index 0000000..8547261
--- /dev/null
+++ b/tests/tests/netlegacy22/permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts.legacy.api22.permission;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import java.net.InetAddress;
+
+/**
+ * Verify ConnectivityManager related methods without specific network state permissions.
+ */
+public class NoNetworkStatePermissionTest extends AndroidTestCase {
+    private ConnectivityManager mConnectivityManager;
+    private static final int TEST_NETWORK_TYPE = ConnectivityManager.TYPE_MOBILE;
+    private static final String TEST_FEATURE = "enableHIPRI";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        assertNotNull(mConnectivityManager);
+    }
+
+    /**
+     * Verify that ConnectivityManager#startUsingNetworkFeature() requires permissions.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testStartUsingNetworkFeature() {
+        try {
+            mConnectivityManager.startUsingNetworkFeature(TEST_NETWORK_TYPE, TEST_FEATURE);
+            fail("ConnectivityManager.startUsingNetworkFeature didn't throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Verify that ConnectivityManager#requestRouteToHost() requires permissions.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testRequestRouteToHost() {
+        try {
+            mConnectivityManager.requestRouteToHost(TEST_NETWORK_TYPE, 0xffffffff);
+            fail("ConnectivityManager.requestRouteToHost didn't throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+}
diff --git a/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
index 0eae9cc..35ebdc1 100644
--- a/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
@@ -86,38 +86,6 @@
         }
     }
 
-    /**
-     * Verify that ConnectivityManager#startUsingNetworkFeature() requires permissions.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
-     */
-    @SmallTest
-    public void testStartUsingNetworkFeature() {
-        try {
-            mConnectivityManager.startUsingNetworkFeature(TEST_NETWORK_TYPE, TEST_FEATURE);
-            fail("ConnectivityManager.startUsingNetworkFeature didn't throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that ConnectivityManager#requestRouteToHost() requires permissions.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
-     */
-    @SmallTest
-    public void testRequestRouteToHost() {
-        try {
-            mConnectivityManager.requestRouteToHost(TEST_NETWORK_TYPE, 0xffffffff);
-            fail("ConnectivityManager.requestRouteToHost didn't throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
     @SmallTest
     public void testSecurityExceptionFromDns() throws Exception {
         try {
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java b/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java
index 52c8317..00a56ac 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java
@@ -51,7 +51,9 @@
 
     @Override
     protected void tearDown() throws Exception {
-        tearDownConnectionServices(TEST_PHONE_ACCOUNT_HANDLE, TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+        if (mShouldTestTelecom) {
+            tearDownConnectionServices(TEST_PHONE_ACCOUNT_HANDLE, TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+        }
         super.tearDown();
     }
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 962df59..4936209 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -63,7 +63,8 @@
             return false;
         }
         final PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
+                pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
     }
 
     public static String setDefaultDialer(Instrumentation instrumentation, String packageName)
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 2b7e093..1df0ddf 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -191,8 +191,6 @@
     for package, test_list in small_tests.iteritems():
       plan.Include(package+'$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
-    for package, test_list in temporarily_known_failure_tests.iteritems():
-      plan.ExcludeTests(package, test_list)
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
@@ -273,9 +271,6 @@
       plan.Exclude(package+'$')
     for package, tests_list in new_test_packages.iteritems():
       plan.Exclude(package+'$')
-    for package, test_list in temporarily_known_failure_tests.iteritems():
-      plan.Include(package+'$')
-      plan.IncludeTests(package, test_list)
     plan.Exclude(r'com\.drawelements\.')
     plan.Exclude(r'android\.hardware$')
     plan.Exclude(r'android\.media$')
@@ -286,6 +281,15 @@
       plan.ExcludeTests(package, test_list)
     for package, test_list in releasekey_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    self.__WritePlan(plan, 'CTS-m-tests')
+
+
+    # CTS - sub plan for new test packages added for staging
+    plan = tools.TestPlan(packages)
+    plan.Exclude('.*')
+    for package, test_list in temporarily_known_failure_tests.iteritems():
+      plan.Include(package+'$')
+      plan.IncludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-staging')
 
     plan = tools.TestPlan(packages)
@@ -461,11 +465,35 @@
   """ Construct a defaultdict that maps package name to a list of tests
       that are known failures during dev cycle but expected to be fixed before launch """
   return {
-      'android.bluetooth' : [
-          'android.bluetooth.cts.BluetoothLeScanTest#testBasicBleScan',
-          'android.bluetooth.cts.BluetoothLeScanTest#testBatchScan',
-          'android.bluetooth.cts.BluetoothLeScanTest#testOpportunisticScan',
-          'android.bluetooth.cts.BluetoothLeScanTest#testScanFilter',],
+      'android.alarmclock' : [
+          'android.alarmclock.cts.DismissAlarmTest#testAll',
+          'android.alarmclock.cts.SetAlarmTest#testAll',
+          'android.alarmclock.cts.SnoozeAlarmTest#testAll',
+      ],
+      'android.calllog' : [
+          'android.calllog.cts.CallLogBackupTest#testSingleCallBackup',
+      ],
+      'android.dumpsys' : [
+          'android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput',
+          'android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats',
+      ],
+      'android.telecom' : [
+          'android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect',
+          'android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections',
+      ],
+      'android.transition' : [
+          'android.transition.cts.ChangeScrollTest#testChangeScroll',
+      ],
+      'android.voicesettings' : [
+          'android.voicesettings.cts.ZenModeTest#testAll',
+      ],
+      'com.android.cts.app.os' : [
+          'com.android.cts.app.os.OsHostTests#testNonExportedActivities',
+      ],
+      'com.android.cts.devicepolicy' : [
+          'com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPackageInstallUserRestrictions',
+          'com.android.cts.devicepolicy.MixedProfileOwnerTest#testPackageInstallUserRestrictions',
+      ],
       '' : []}
 
 def LogGenerateDescription(name):