Merge "Make packet count test more robust" into jb-mr1-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index c93fafb..8c2b798 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -25,7 +25,8 @@
 	CtsSimpleAppInstallDiffCert \
 	CtsTargetInstrumentationApp \
 	CtsUsePermissionDiffCert \
-	CtsWriteExternalStorageApp
+	CtsWriteExternalStorageApp \
+	CtsMultiUserStorageApp
 
 cts_support_packages := \
 	CtsAccelerationTestStubs \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 6fcb9ca..e588d05 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -70,7 +70,7 @@
         </activity>
 
         <activity android:name=".ReportViewerActivity"
-                android:configChanges="keyboardHidden|orientation"
+                android:configChanges="keyboardHidden|orientation|screenSize"
                 android:label="@string/report_viewer" />
 
         <provider android:name=".TestResultsProvider" 
@@ -78,7 +78,7 @@
 
         <activity android:name=".admin.PolicySerializationTestActivity"
                 android:label="@string/da_policy_serialization_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -88,7 +88,7 @@
 
         <activity android:name=".admin.ScreenLockTestActivity"
                 android:label="@string/da_screen_lock_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -114,7 +114,7 @@
 
         <activity android:name=".bluetooth.BluetoothTestActivity"
                 android:label="@string/bluetooth_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -125,7 +125,7 @@
 
         <activity android:name=".bluetooth.BluetoothToggleActivity"
                 android:label="@string/bt_toggle_bluetooth"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -136,7 +136,7 @@
 
         <activity android:name=".bluetooth.SecureServerActivity"
                 android:label="@string/bt_secure_server"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -147,7 +147,7 @@
 
         <activity android:name=".bluetooth.InsecureServerActivity"
                 android:label="@string/bt_insecure_server"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -158,7 +158,7 @@
 
         <activity android:name=".bluetooth.SecureClientActivity"
                 android:label="@string/bt_secure_client"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -169,7 +169,7 @@
 
         <activity android:name=".bluetooth.InsecureClientActivity"
                 android:label="@string/bt_insecure_client"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -180,7 +180,7 @@
 
         <activity android:name=".bluetooth.ConnectionAccessServerActivity"
                 android:label="@string/bt_connection_access_server"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
@@ -190,7 +190,7 @@
 
         <activity android:name=".bluetooth.ConnectionAccessClientActivity"
                 android:label="@string/bt_connection_access_client"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
@@ -200,11 +200,11 @@
 
         <activity android:name=".bluetooth.DevicePickerActivity"
                 android:label="@string/bt_device_picker"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".suid.SuidFilesActivity"
                 android:label="@string/suid_files"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -214,7 +214,7 @@
 
         <activity android:name=".streamquality.StreamingVideoActivity"
                 android:label="@string/streaming_video"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -224,7 +224,7 @@
 
         <activity android:name=".streamquality.PlayVideoActivity"
                 android:label="@string/streaming_video"
-                android:configChanges="keyboardHidden|orientation"
+                android:configChanges="keyboardHidden|orientation|screenSize"
                 android:screenOrientation="nosensor" />
 
         <activity android:name=".features.FeatureSummaryActivity" android:label="@string/feature_summary">
@@ -237,7 +237,7 @@
 
         <activity android:name=".location.GpsTestActivity"
                 android:label="@string/location_gps_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -248,7 +248,7 @@
 
         <activity android:name=".nfc.NfcTestActivity"
                 android:label="@string/nfc_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -259,15 +259,15 @@
 
         <activity android:name=".nfc.NdefPushSenderActivity"
                 android:label="@string/nfc_ndef_push_sender"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".nfc.NdefPushReceiverActivity"
                 android:label="@string/nfc_ndef_push_receiver"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".nfc.TagVerifierActivity"
                 android:label="@string/nfc_tag_verifier"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".sensors.AccelerometerTestActivity" android:label="@string/snsr_accel_test"
                 android:screenOrientation="nosensor">
@@ -332,7 +332,7 @@
 
         <activity android:name=".usb.UsbAccessoryTestActivity"
                 android:label="@string/usb_accessory_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -343,7 +343,7 @@
 
         <activity android:name=".p2p.P2pTestListActivity"
                 android:label="@string/p2p_test"
-                android:configChanges="keyboardHidden|orientation">
+                android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -354,39 +354,39 @@
 
         <activity android:name=".p2p.GoNegRequesterTestListActivity"
                 android:label="@string/p2p_go_neg_requester"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.GoNegRequesterTestActivity"
                 android:label="@string/p2p_go_neg_requester"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.GoNegResponderTestActivity"
                 android:label="@string/p2p_go_neg_responder"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.P2pClientTestListActivity"
                 android:label="@string/p2p_join_go"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.P2pClientTestActivity"
                 android:label="@string/p2p_join_go"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.GoTestActivity"
                 android:label="@string/p2p_accept_client"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.ServiceRequesterTestListActivity"
                 android:label="@string/p2p_service_discovery_requester"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.ServiceRequesterTestActivity"
                 android:label="@string/p2p_service_discovery_requester"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity android:name=".p2p.ServiceResponderTestActivity"
                 android:label="@string/p2p_service_discovery_responder"
-                android:configChanges="keyboardHidden|orientation" />
+                android:configChanges="keyboardHidden|orientation|screenSize" />
 
         <activity-alias android:name=".CtsVerifierActivity" android:label="@string/app_name"
                 android:targetActivity=".TestListActivity">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
index 56a3b44..be0ef01 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
@@ -45,12 +45,14 @@
     private int mNumActiveUpdates = 0;
     private int mNumPassiveUpdates = 0;
     private boolean mRunning = false;
+    private boolean mActiveLocationArrive = false;
 
     private class ActiveListener implements LocationListener {
         @Override
         public void onLocationChanged(Location location) {
             if (!mRunning) return;
 
+            mActiveLocationArrive = true;
             mNumActiveUpdates++;
             scheduleTimeout();
 
@@ -103,6 +105,15 @@
             if (!mRunning) return;
             if (!location.getProvider().equals(mProvider)) return;
 
+            // When a test round start, passive listener shouldn't recevice location before active listener.
+            // If this situation occurs, we treat this location as overdue location.
+            // (The overdue location comes from previous test round, it occurs occasionally)
+            // We have to skip it to prevent wrong calculation of time interval.
+            if (!mActiveLocationArrive) {
+                mCb.log("ignoring passive " + mProvider + " update");
+                return;
+            }
+
             mNumPassiveUpdates++;
             long timestamp = location.getTime();
             long delta = timestamp - mLastPassiveTimestamp;
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
index 5c28a4f..7e65be3 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
@@ -19,15 +19,17 @@
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.InstrumentationResultParser;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.CollectingTestListener;
 import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
 import com.android.tradefed.result.TestResult.TestStatus;
+import com.android.tradefed.result.TestRunResult;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
@@ -94,6 +96,11 @@
 
     private static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
 
+    private static final String MULTIUSER_STORAGE_APK = "CtsMultiUserStorageApp.apk";
+    private static final String MULTIUSER_STORAGE_PKG = "com.android.cts.multiuserstorageapp";
+    private static final String MULTIUSER_STORAGE_CLASS = MULTIUSER_STORAGE_PKG
+            + ".MultiUserStorageTest";
+
     private static final String LOG_TAG = "AppSecurityTests";
 
     private CtsBuildHelper mCtsBuild;
@@ -242,6 +249,25 @@
     }
 
     /**
+     * Verify that legacy filesystem paths continue working, and that they all
+     * point to same location.
+     */
+    public void testExternalStorageLegacyPaths() throws Exception {
+        try {
+            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
+            assertNull(getDevice()
+                    .installPackage(getTestAppFile(WRITE_EXTERNAL_STORAGE_APP_APK), false));
+
+            assertTrue("Failed to verify legacy filesystem paths", runDeviceTests(
+                    WRITE_EXTERNAL_STORAGE_APP_PKG, WRITE_EXTERNAL_STORAGE_APP_CLASS,
+                    "testLegacyPaths"));
+
+        } finally {
+            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
+        }
+    }
+
+    /**
      * Test that uninstall of an app removes its private data.
      */
     public void testUninstallRemovesData() throws Exception {
@@ -346,6 +372,73 @@
     }
 
     /**
+     * Test multi-user emulated storage environment, ensuring that each user has
+     * isolated storage minus shared OBB directory.
+     */
+    public void testMultiUserStorage() throws Exception {
+        final String PACKAGE = MULTIUSER_STORAGE_PKG;
+        final String CLAZZ = MULTIUSER_STORAGE_CLASS;
+
+        if (!isMultiUserSupportedOnDevice(getDevice())) {
+            Log.d(LOG_TAG, "Single user device; skipping isolated storage tests");
+            return;
+        }
+
+        int owner = 0;
+        int secondary = -1;
+        try {
+            // Create secondary user
+            secondary = createUserOnDevice(getDevice());
+
+            // Install our test app
+            getDevice().uninstallPackage(MULTIUSER_STORAGE_PKG);
+            final String installResult = getDevice()
+                    .installPackage(getTestAppFile(MULTIUSER_STORAGE_APK), false);
+            assertNull("Failed to install: " + installResult, installResult);
+
+            // Clear data from previous tests
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanIsolatedStorage", owner));
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanIsolatedStorage", secondary));
+
+            // Have both users try writing into isolated storage
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "writeIsolatedStorage", owner));
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "writeIsolatedStorage", secondary));
+
+            // Verify they both have isolated view of storage
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "readIsolatedStorage", owner));
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "readIsolatedStorage", secondary));
+
+            // Clear data from previous tests
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanObbStorage", owner));
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanObbStorage", secondary));
+
+            // Only write data as owner
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "writeObbStorage", owner));
+
+            // Verify that both users can see shared OBB data
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "readObbStorage", owner));
+            assertDeviceTestsPass(
+                    doRunTestsAsUser(PACKAGE, CLAZZ, "readObbStorage", secondary));
+
+        } finally {
+            getDevice().uninstallPackage(MULTIUSER_STORAGE_PKG);
+            if (secondary != -1) {
+                removeUserOnDevice(getDevice(), secondary);
+            }
+        }
+    }
+
+    /**
      * Helper method that checks that all tests in given result passed, and attempts to generate
      * a meaningful error message if they failed.
      *
@@ -415,6 +508,58 @@
         return listener.getCurrentRunResults();
     }
 
+    private static boolean isMultiUserSupportedOnDevice(ITestDevice device)
+            throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String output = device.executeShellCommand("pm get-max-users");
+        try {
+            return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim()) > 1;
+        } catch (NumberFormatException e) {
+            fail("Failed to parse result: " + output);
+        }
+        return false;
+    }
+
+    private static int createUserOnDevice(ITestDevice device) throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String name = "CTS_" + System.currentTimeMillis();
+        final String output = device.executeShellCommand("pm create-user " + name);
+        if (output.startsWith("Success")) {
+            try {
+                return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+            } catch (NumberFormatException e) {
+                fail("Failed to parse result: " + output);
+            }
+        } else {
+            fail("Failed to create user: " + output);
+        }
+        throw new IllegalStateException();
+    }
+
+    private static void removeUserOnDevice(ITestDevice device, int userId)
+            throws DeviceNotAvailableException {
+        // TODO: move this to ITestDevice once it supports users
+        final String output = device.executeShellCommand("pm remove-user " + userId);
+        if (output.startsWith("Error")) {
+            fail("Failed to remove user: " + output);
+        }
+    }
+
+    private TestRunResult doRunTestsAsUser(
+            String pkgName, String testClassName, String testMethodName, int userId)
+            throws DeviceNotAvailableException {
+        // TODO: move this to RemoteAndroidTestRunner once it supports users
+        final String cmd = "am instrument --user " + userId + " -w -r -e class " + testClassName
+                + "#" + testMethodName + " " + pkgName + "/android.test.InstrumentationTestRunner";
+        Log.i(LOG_TAG, "Running " + cmd + " on " + getDevice().getSerialNumber());
+
+        CollectingTestListener listener = new CollectingTestListener();
+        InstrumentationResultParser parser = new InstrumentationResultParser(pkgName, listener);
+
+        getDevice().executeShellCommand(cmd, parser);
+        return listener.getCurrentRunResults();
+    }
+
     private static void setPermissionEnforced(
             ITestDevice device, String permission, boolean enforced)
             throws DeviceNotAvailableException {
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
new file mode 100644
index 0000000..8781e8b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := 16
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := CtsMultiUserStorageApp
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/AndroidManifest.xml
new file mode 100644
index 0000000..6ace31b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     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.multiuserstorageapp">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.cts.multiuserstorageapp" />
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
new file mode 100644
index 0000000..7e2d3ed
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.multiuserstorageapp;
+
+import android.os.Environment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Test multi-user emulated storage environment, ensuring that each user has
+ * isolated storage minus shared OBB directory.
+ */
+public class MultiUserStorageTest extends AndroidTestCase {
+    private static final String TAG = "MultiUserStorageTest";
+
+    private static final String FILE_PREFIX = "MUST_";
+
+    private static final int MAGIC_VALUE = 16785407;
+
+    private final File mTargetSame = new File(
+            Environment.getExternalStorageDirectory(), FILE_PREFIX + "same");
+    private final File mTargetUid = new File(
+            Environment.getExternalStorageDirectory(), FILE_PREFIX + android.os.Process.myUid());
+
+    private File getFileObbSame() {
+        return new File(getContext().getObbDir(), FILE_PREFIX + "obb_same");
+    }
+
+    private void wipeTestFiles(File dir) {
+        dir.mkdirs();
+        for (File file : dir.listFiles()) {
+            if (file.getName().startsWith(FILE_PREFIX)) {
+                Log.d(TAG, "Wiping " + file);
+                file.delete();
+            }
+        }
+    }
+
+    public void cleanIsolatedStorage() throws Exception {
+        wipeTestFiles(Environment.getExternalStorageDirectory());
+    }
+
+    public void writeIsolatedStorage() throws Exception {
+        writeInt(mTargetSame, android.os.Process.myUid());
+        writeInt(mTargetUid, android.os.Process.myUid());
+    }
+
+    public void readIsolatedStorage() throws Exception {
+        // Expect that the value we wrote earlier is still valid and wasn't
+        // overwritten by us running as another user.
+        assertEquals(android.os.Process.myUid(), readInt(mTargetSame));
+        assertEquals(android.os.Process.myUid(), readInt(mTargetUid));
+    }
+
+    public void cleanObbStorage() throws Exception {
+        wipeTestFiles(getContext().getObbDir());
+    }
+
+    public void writeObbStorage() throws Exception {
+        writeInt(getFileObbSame(), MAGIC_VALUE);
+    }
+
+    public void readObbStorage() throws Exception {
+        assertEquals(MAGIC_VALUE, readInt(getFileObbSame()));
+    }
+
+    private static void writeInt(File file, int value) throws IOException {
+        final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
+        try {
+            os.writeInt(value);
+        } finally {
+            os.close();
+        }
+    }
+
+    private static int readInt(File file) throws IOException {
+        final DataInputStream is = new DataInputStream(new FileInputStream(file));
+        try {
+            return is.readInt();
+        } finally {
+            is.close();
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
index b899bb0..075fe2e 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
@@ -19,48 +19,49 @@
 import android.os.Environment;
 import android.test.AndroidTestCase;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.util.Random;
 
 /**
  * Test if {@link Environment#getExternalStorageDirectory()} is writable.
  */
 public class WriteExternalStorageTest extends AndroidTestCase {
 
-    private static final String TEST_FILE = "meow";
+    private static final File TEST_FILE = new File(
+            Environment.getExternalStorageDirectory(), "meow");
 
-    private void assertExternalStorageMounted() {
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-    }
+    /**
+     * Set of file paths that should all refer to the same location to verify
+     * support for legacy paths.
+     */
+    private static final File[] IDENTICAL_FILES = {
+            new File("/sdcard/caek"),
+            new File("/mnt/sdcard/caek"),
+            new File("/storage/sdcard0/caek"),
+            new File(Environment.getExternalStorageDirectory(), "caek"),
+    };
 
-    private void readExternalStorage() throws IOException {
-        final File file = new File(Environment.getExternalStorageDirectory(), TEST_FILE);
-        final InputStream is = new FileInputStream(file);
+    @Override
+    protected void tearDown() throws Exception {
         try {
-            is.read();
+            TEST_FILE.delete();
+            for (File file : IDENTICAL_FILES) {
+                file.delete();
+            }
         } finally {
-            is.close();
-        }
-    }
-
-    private void writeExternalStorage() throws IOException {
-        final File file = new File(Environment.getExternalStorageDirectory(), TEST_FILE);
-        final OutputStream os = new FileOutputStream(file);
-        try {
-            os.write(32);
-        } finally {
-            os.close();
+            super.tearDown();
         }
     }
 
     public void testReadExternalStorage() throws Exception {
         assertExternalStorageMounted();
         try {
-            readExternalStorage();
+            writeInt(TEST_FILE, 32);
         } catch (IOException e) {
             fail("unable to read external file");
         }
@@ -69,10 +70,54 @@
     public void testWriteExternalStorage() throws Exception {
         assertExternalStorageMounted();
         try {
-            writeExternalStorage();
+            assertEquals(readInt(TEST_FILE), 32);
         } catch (IOException e) {
             fail("unable to read external file");
         }
     }
 
+    /**
+     * Verify that legacy filesystem paths continue working, and that they all
+     * point to same location.
+     */
+    public void testLegacyPaths() throws Exception {
+        final Random r = new Random();
+        for (File target : IDENTICAL_FILES) {
+            // Ensure we're starting with clean slate
+            for (File file : IDENTICAL_FILES) {
+                file.delete();
+            }
+
+            // Write value to our current target
+            final int value = r.nextInt();
+            writeInt(target, value);
+
+            // Ensure that identical files all contain the value
+            for (File file : IDENTICAL_FILES) {
+                assertEquals(readInt(file), value);
+            }
+        }
+    }
+
+    private static void assertExternalStorageMounted() {
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+    }
+
+    private static void writeInt(File file, int value) throws IOException {
+        final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
+        try {
+            os.writeInt(value);
+        } finally {
+            os.close();
+        }
+    }
+
+    private static int readInt(File file) throws IOException {
+        final DataInputStream is = new DataInputStream(new FileInputStream(file));
+        try {
+            return is.readInt();
+        } finally {
+            is.close();
+        }
+    }
 }
diff --git a/tests/src/android/renderscript/cts/scriptgroup.rs b/tests/src/android/renderscript/cts/scriptgroup.rs
new file mode 100644
index 0000000..91527f8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/scriptgroup.rs
@@ -0,0 +1,49 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#include "shared.rsh"
+
+int memset_toValue = 0;
+
+int compare_value = 0;
+int compare_failure = 2;
+
+// 0 = +, 1 = -, 2 = *, 3 = /
+int arith_operation = 0;
+int arith_use_rs_allocation = 0;
+rs_allocation arith_rs_input;
+int arith_value = 0;
+
+void arith(const int *ain, int *aout, uint32_t x) {
+    int value = arith_value;
+
+    if (arith_use_rs_allocation)
+        value = *(int*)(rsGetElementAt(arith_rs_input, x));
+
+    if (arith_operation == 0) {
+        *aout = *ain + value;
+    } else if (arith_operation == 1) {
+        *aout = *ain - value;
+    } else if (arith_operation == 2) {
+        *aout = *ain * value;
+    } else if (arith_operation == 3) {
+        *aout = *ain / value;
+    }
+
+}
+
+void memset(int *aout) {
+    *aout = memset_toValue;
+    return;
+}
+
+void compare(const int *ain) {
+    if (*ain != compare_value) {
+        rsAtomicCas(&compare_failure, 2, -1);
+    }
+    return;
+}
+
+void getCompareResult(int* aout) {
+    *aout = compare_failure;
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index e64da89..8616a6d 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -31,9 +31,10 @@
  * BluetoothAdapter}.
  */
 public class BasicAdapterTest extends AndroidTestCase {
-    private static final int DISABLE_TIMEOUT = 5000;  // ms timeout for BT disable
+    private static final int DISABLE_TIMEOUT = 8000;  // ms timeout for BT disable
     private static final int ENABLE_TIMEOUT = 10000;  // ms timeout for BT enable
     private static final int POLL_TIME = 400;         // ms to poll BT state
+    private static final int CHECK_WAIT_TIME = 1000;  // ms to wait before enable/disable
 
     private boolean mHasBluetooth;
 
@@ -222,6 +223,7 @@
      * Behavior of getState() and isEnabled() are validated along the way.
      */
     private void disable(BluetoothAdapter adapter) {
+        sleep(CHECK_WAIT_TIME);
         if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
             assertFalse(adapter.isEnabled());
             return;
@@ -230,15 +232,19 @@
         assertEquals(BluetoothAdapter.STATE_ON, adapter.getState());
         assertTrue(adapter.isEnabled());
         adapter.disable();
+        boolean turnOff = false;
         for (int i=0; i<DISABLE_TIMEOUT/POLL_TIME; i++) {
             sleep(POLL_TIME);
-            switch (adapter.getState()) {
+            int state = adapter.getState();
+            switch (state) {
             case BluetoothAdapter.STATE_OFF:
                 assertFalse(adapter.isEnabled());
                 return;
             default:
-                assertEquals(BluetoothAdapter.STATE_TURNING_OFF, adapter.getState());
-                assertFalse(adapter.isEnabled());
+                if (state != BluetoothAdapter.STATE_ON || turnOff) {
+                    assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
+                    turnOff = true;
+                }
                 break;
             }
         }
@@ -250,6 +256,7 @@
      * Behavior of getState() and isEnabled() are validated along the way.
      */
     private void enable(BluetoothAdapter adapter) {
+        sleep(CHECK_WAIT_TIME);
         if (adapter.getState() == BluetoothAdapter.STATE_ON) {
             assertTrue(adapter.isEnabled());
             return;
@@ -258,15 +265,19 @@
         assertEquals(BluetoothAdapter.STATE_OFF, adapter.getState());
         assertFalse(adapter.isEnabled());
         adapter.enable();
+        boolean turnOn = false;
         for (int i=0; i<ENABLE_TIMEOUT/POLL_TIME; i++) {
             sleep(POLL_TIME);
-            switch (adapter.getState()) {
+            int state = adapter.getState();
+            switch (state) {
             case BluetoothAdapter.STATE_ON:
                 assertTrue(adapter.isEnabled());
                 return;
             default:
-                assertEquals(BluetoothAdapter.STATE_TURNING_ON, adapter.getState());
-                assertFalse(adapter.isEnabled());
+                if (state != BluetoothAdapter.STATE_OFF || turnOn) {
+                    assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
+                    turnOn = true;
+                }
                 break;
             }
         }
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsTest.java b/tests/tests/provider/src/android/provider/cts/SettingsTest.java
index 601efce..3ea47d4 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsTest.java
@@ -180,8 +180,8 @@
         // Test that the secure table can be read from.
         Cursor cursor = null;
         try {
-            cursor = provider.query(Settings.Secure.CONTENT_URI, SECURE_PROJECTION,
-                    Settings.Secure.NAME + "=\"" + Settings.Secure.ADB_ENABLED + "\"",
+            cursor = provider.query(Settings.Global.CONTENT_URI, SECURE_PROJECTION,
+                    Settings.Global.NAME + "=\"" + Settings.Global.ADB_ENABLED + "\"",
                     null, null, null);
             assertNotNull(cursor);
         } finally {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
new file mode 100644
index 0000000..e73195c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2011-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.AllocationAdapter;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.RSInvalidStateException;
+import android.renderscript.Type;
+import android.renderscript.Type.Builder;
+
+import android.renderscript.ScriptIntrinsicColorMatrix;
+import android.renderscript.ScriptIntrinsicConvolve3x3;
+import android.renderscript.ScriptGroup;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+public class ScriptGroupTest extends RSBaseCompute {
+
+    static int bDimX = 48;
+    static int bDimY = 8;
+
+    public void testScriptGroupSingleKernel() {
+        ScriptGroup group;
+
+        Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create();
+
+        ScriptIntrinsicColorMatrix mColorMatrix;
+
+        mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+
+        Allocation a1_copy, a2_copy;
+        a1_copy = Allocation.createTyped(mRS, connect);
+        a2_copy = Allocation.createTyped(mRS, connect);
+
+        Matrix4f m = new Matrix4f();
+        m.set(1, 0, 0.2f);
+        m.set(1, 1, 0.9f);
+        m.set(1, 2, 0.2f);
+        mColorMatrix.setColorMatrix(m);
+
+        ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+        b.addKernel(mColorMatrix.getKernelID());
+        group = b.create();
+
+        group.setInput(mColorMatrix.getKernelID(), a1_copy);
+        group.setOutput(mColorMatrix.getKernelID(), a2_copy);
+
+        group.execute();
+    }
+
+    public void testScriptGroupDisconnectedKernel() {
+        ScriptGroup group;
+
+        Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create();
+
+        ScriptIntrinsicColorMatrix mColorMatrix, mColorMatrix2;
+
+        mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+        mColorMatrix2 = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+
+        Allocation a1_copy, a2_copy;
+
+        a1_copy = Allocation.createTyped(mRS, connect);
+        a2_copy = Allocation.createTyped(mRS, connect);
+
+        Matrix4f m = new Matrix4f();
+        m.set(1, 0, 0.2f);
+        m.set(1, 1, 0.9f);
+        m.set(1, 2, 0.2f);
+        mColorMatrix.setColorMatrix(m);
+        mColorMatrix2.setColorMatrix(m);
+
+        ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+        b.addKernel(mColorMatrix.getKernelID());
+        b.addKernel(mColorMatrix2.getKernelID());
+        try {
+            group = b.create();
+            fail("should throw RSInvalidStateException.");
+        } catch (RSInvalidStateException e) {
+
+        }
+    }
+
+
+    public void testScriptGroupFieldConnection() {
+        ScriptGroup group;
+
+        Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create();
+
+        ScriptIntrinsicConvolve3x3 mConvolve3x3;
+        ScriptIntrinsicColorMatrix mColorMatrix;
+
+        mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
+        mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+
+        Allocation a1_copy, a2_copy;
+        a1_copy = Allocation.createTyped(mRS, connect);
+        a2_copy = Allocation.createTyped(mRS, connect);
+
+        float f[] = new float[9];
+        f[0] =  0.f;    f[1] = -1.f;    f[2] =  0.f;
+        f[3] = -1.f;    f[4] =  5.f;    f[5] = -1.f;
+        f[6] =  0.f;    f[7] = -1.f;    f[8] =  0.f;
+
+        mConvolve3x3.setCoefficients(f);
+
+        Matrix4f m = new Matrix4f();
+        m.set(1, 0, 0.2f);
+        m.set(1, 1, 0.9f);
+        m.set(1, 2, 0.2f);
+        mColorMatrix.setColorMatrix(m);
+
+        ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+        b.addKernel(mColorMatrix.getKernelID());
+        b.addKernel(mConvolve3x3.getKernelID());
+        b.addConnection(connect, mColorMatrix.getKernelID(), mConvolve3x3.getFieldID_Input());
+        group = b.create();
+
+        group.setInput(mColorMatrix.getKernelID(), a1_copy);
+        group.setOutput(mConvolve3x3.getKernelID(), a2_copy);
+
+        group.execute();
+
+    }
+
+    public void testScriptGroupDisconnectedDAG() {
+        ScriptGroup group;
+
+        Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create();
+
+        ScriptIntrinsicConvolve3x3 mConvolve3x3, mConvolve3x32;
+        ScriptIntrinsicColorMatrix mColorMatrix, mColorMatrix2;
+
+        mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
+        mConvolve3x32 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
+        mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+        mColorMatrix2 = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+
+        Allocation a1_copy, a2_copy;
+        a1_copy = Allocation.createTyped(mRS, connect);
+        a2_copy = Allocation.createTyped(mRS, connect);
+
+        float f[] = new float[9];
+        f[0] =  0.f;    f[1] = -1.f;    f[2] =  0.f;
+        f[3] = -1.f;    f[4] =  5.f;    f[5] = -1.f;
+        f[6] =  0.f;    f[7] = -1.f;    f[8] =  0.f;
+
+        mConvolve3x3.setCoefficients(f);
+        mConvolve3x32.setCoefficients(f);
+
+        Matrix4f m = new Matrix4f();
+        m.set(1, 0, 0.2f);
+        m.set(1, 1, 0.9f);
+        m.set(1, 2, 0.2f);
+        mColorMatrix.setColorMatrix(m);
+        mColorMatrix2.setColorMatrix(m);
+
+        ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+        b.addKernel(mColorMatrix.getKernelID());
+        b.addKernel(mColorMatrix2.getKernelID());
+        b.addKernel(mConvolve3x3.getKernelID());
+        b.addKernel(mConvolve3x32.getKernelID());
+        b.addConnection(connect, mColorMatrix.getKernelID(), mConvolve3x3.getFieldID_Input());
+        b.addConnection(connect, mColorMatrix2.getKernelID(), mConvolve3x32.getFieldID_Input());
+        try {
+            group = b.create();
+            fail("RSInvalidStateException expected");
+        } catch (RSInvalidStateException e) {
+
+        }
+
+    }
+
+    public void testScriptGroupTorture() {
+        ScriptGroup group;
+
+        int[] result = new int[1];
+
+        bDimX = 1;
+
+        Type connect = new Type.Builder(mRS, Element.I32(mRS)).setX(bDimX).create();
+        Type compareType = new Type.Builder(mRS, Element.I32(mRS)).create();
+
+        ScriptC_scriptgroup node1, node2, node3, node4, node5, compare;
+        node1 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+        node2 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+        node3 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+        node4 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+        node5 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+
+        compare = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+
+        Allocation in1, in2, out, resultAlloc;
+        in1 = Allocation.createTyped(mRS, connect);
+        in2 = Allocation.createTyped(mRS, connect);
+
+        out = Allocation.createTyped(mRS, connect);
+        resultAlloc = Allocation.createTyped(mRS, compareType);
+
+        node1.set_memset_toValue(1);
+        node1.forEach_memset(in1);
+        node1.set_memset_toValue(2);
+        node1.forEach_memset(in2);
+
+        node1.set_arith_operation(2);
+        node2.set_arith_operation(1);
+        node3.set_arith_operation(0);
+        node4.set_arith_operation(0);
+        node5.set_arith_operation(1);
+
+        node3.set_arith_use_rs_allocation(1);
+        node4.set_arith_use_rs_allocation(1);
+
+        node1.set_arith_value(5);
+        node2.set_arith_value(3);
+        node5.set_arith_value(7);
+
+        ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+        b.addKernel(node1.getKernelID_arith());
+        b.addKernel(node2.getKernelID_arith());
+        b.addKernel(node3.getKernelID_arith());
+        b.addKernel(node4.getKernelID_arith());
+        b.addKernel(node5.getKernelID_arith());
+
+        b.addConnection(connect, node1.getKernelID_arith(), node2.getKernelID_arith());
+        b.addConnection(connect, node1.getKernelID_arith(), node3.getFieldID_arith_rs_input());
+        b.addConnection(connect, node2.getKernelID_arith(), node4.getFieldID_arith_rs_input());
+        b.addConnection(connect, node3.getKernelID_arith(), node4.getKernelID_arith());
+        b.addConnection(connect, node4.getKernelID_arith(), node5.getKernelID_arith());
+
+        group = b.create();
+        group.setInput(node1.getKernelID_arith(), in1);
+        group.setInput(node3.getKernelID_arith(), in2);
+
+        group.setOutput(node5.getKernelID_arith(), out);
+
+        group.execute();
+
+        mRS.finish();
+
+        compare.set_compare_value(2);
+        compare.forEach_compare(out);
+        compare.forEach_getCompareResult(resultAlloc);
+        resultAlloc.copyTo(result);
+        Log.e("ARGH", "result = " + result[0]);
+        assertTrue(result[0] == 2);
+    }
+
+}
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
new file mode 100644
index 0000000..45f3d51
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.os.IBinder;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+/**
+ * Verifies that permissions are enforced on various system services.
+ */
+public class ServicePermissionsTest extends AndroidTestCase {
+
+    private static final String TAG = "ServicePermissionsTest";
+
+    private File mTempFile;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTempFile = new File(getContext().getCacheDir(), "CTS_DUMP");
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            mTempFile.delete();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    /**
+     * Test that {@link IBinder#dump(java.io.FileDescriptor, String[])} on all
+     * registered system services checks if caller holds
+     * {@link android.Manifest.permission#DUMP} permission.
+     */
+    public void testDumpProtected() throws Exception {
+
+        String[] services = null;
+        try {
+            services = (String[]) Class.forName("android.os.ServiceManager")
+                    .getDeclaredMethod("listServices").invoke(null);
+        } catch (ClassCastException e) {
+        } catch (ClassNotFoundException e) {
+        } catch (NoSuchMethodException e) {
+        } catch (InvocationTargetException e) {
+        } catch (IllegalAccessException e) {
+        }
+
+        if ((services == null) || (services.length == 0)) {
+            Log.w(TAG, "No registered services, that's odd");
+            return;
+        }
+
+        for (String service : services) {
+            mTempFile.delete();
+
+            IBinder serviceBinder = null;
+            try {
+                serviceBinder = (IBinder) Class.forName("android.os.ServiceManager")
+                        .getDeclaredMethod("getService", String.class).invoke(null, service);
+            } catch (ClassCastException e) {
+            } catch (ClassNotFoundException e) {
+            } catch (NoSuchMethodException e) {
+            } catch (InvocationTargetException e) {
+            } catch (IllegalAccessException e) {
+            }
+
+            if (serviceBinder == null) {
+                Log.w(TAG, "Missing service " + service);
+                continue;
+            }
+
+            Log.d(TAG, "Dumping service " + service);
+            final FileOutputStream out = new FileOutputStream(mTempFile);
+            try {
+                serviceBinder.dump(out.getFD(), new String[0]);
+            } catch (SecurityException e) {
+                if (e.getMessage().contains("android.permission.DUMP")) {
+                    // Service correctly checked for DUMP permission, yay
+                } else {
+                    // Service is throwing about something else; they're
+                    // probably not checking for DUMP.
+                    throw e;
+                }
+            } finally {
+                out.close();
+            }
+
+            // Verify that dump produced minimal output
+            final BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(new FileInputStream(mTempFile)));
+            final ArrayList<String> lines = new ArrayList<String>();
+            try {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    lines.add(line);
+                    Log.v(TAG, "--> " + line);
+                }
+            } finally {
+                reader.close();
+            }
+
+            if (lines.size() > 1) {
+                fail("dump() for " + service + " produced several lines of output; this "
+                        + "may be leaking sensitive data.  At most, services should emit a "
+                        + "single line when the caller doesn't have DUMP permission.");
+            }
+
+            if (lines.size() == 1) {
+                if (!lines.get(0).contains("Permission Denial")) {
+                    fail("dump() for " + service + " produced a single line which didn't "
+                            + "reference a permission; it may be leaking sensitive data.");
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/textureview/src/android/textureview/cts/TextureViewSnapshotTest.java b/tests/tests/textureview/src/android/textureview/cts/TextureViewSnapshotTest.java
index 6195e5c..c056786 100644
--- a/tests/tests/textureview/src/android/textureview/cts/TextureViewSnapshotTest.java
+++ b/tests/tests/textureview/src/android/textureview/cts/TextureViewSnapshotTest.java
@@ -25,7 +25,7 @@
     }
 
     public void testTextureViewGrabSnapshot() {
-        TextureViewSnapshotTestActivity.mMaxWaitDelayMs = 750;
+        TextureViewSnapshotTestActivity.mMaxWaitDelayMs = 1500;
         if (!getActivity().waitForCompletion())
             fail("Did not complete complete test.");
     }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 8e59cc5..f014135 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -174,7 +174,7 @@
         helpBuilder.append("Dump:\n");
         helpBuilder.append("  d/dump l/logs: dump the tradefed logs for all running invocations\n");
         helpBuilder.append("Options:\n");
-        helpBuilder.append("  --reboot-per-package : reboot device after running each package.\n");
+        helpBuilder.append("  --disable-reboot : Do not reboot device after running some amount of tests.\n");
         return helpBuilder.toString();
     }
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 7699ef1..55d947e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -137,16 +137,16 @@
         "run tests including known failures")
     private boolean mIncludeKnownFailures;
 
-    @Option(name = "reboot-per-package", description =
-            "Reboot after each package run")
-    private boolean mRebootPerPackage = false;
+    @Option(name = "disable-reboot", description =
+            "Do not reboot device after running some amount of tests. Default behavior is to reboot.")
+    private boolean mDisableReboot = false;
 
     @Option(name = "reboot-wait-time", description =
-            "Additional wait time in ms after boot complete. Meaningful only with reboot-per-package option")
+            "Additional wait time in ms after boot complete.")
     private int mRebootWaitTimeMSec = 2 * 60 * 1000;
 
     @Option(name = "reboot-interval", description =
-            "Interval between each reboot in min. Meaningful only with reboot-per-package option")
+            "Interval between each reboot in min.")
     private int mRebootIntervalMin = 30;
 
 
@@ -350,7 +350,7 @@
             // always collect the device info, even for resumed runs, since test will likely be
             // running on a different device
             collectDeviceInfo(getDevice(), mCtsBuild, listener);
-            if (mRemainingTestPkgs.size() > 1) {
+            if (mRemainingTestPkgs.size() > 1 && !mDisableReboot) {
                 Log.i(LOG_TAG, "Initial reboot for multiple packages");
                 rebootDevice();
             }
@@ -405,7 +405,7 @@
                 "CtsViewTestCases",
                 "CtsWidgetTestCases" );
         long intervalInMSec = mRebootIntervalMin * 60 * 1000;
-        if (mRebootPerPackage) {
+        if (!mDisableReboot) {
             long currentTime = System.currentTimeMillis();
             if (((currentTime - mPrevRebootTime) > intervalInMSec) ||
                     rebootAfterList.contains(testFinished.getPackageDef().getName()) ||