Merge "Optimizing AccessibilityNodeInfo caching (CTS)."
diff --git a/tests/deviceadmin/AndroidManifest.xml b/tests/deviceadmin/AndroidManifest.xml
index f851e6c..69bc74d 100644
--- a/tests/deviceadmin/AndroidManifest.xml
+++ b/tests/deviceadmin/AndroidManifest.xml
@@ -40,6 +40,60 @@
             </intent-filter>
         </receiver>
 
+        <!-- Helper Activity used by Device Admin activation tests -->
+        <activity android:name="android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity"
+                android:label="Device Admin activation test" />
+
+        <!-- Broken device admin: meta-data missing -->
+        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: filter doesn't match an Intent with action
+             android.app.action.DEVICE_ADMIN_ENABLED and nothing else (e.g.,
+             data) set -->
+        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver2"
+                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" />
+                <data android:scheme="https" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: meta-data element doesn't point to valid
+             Device Admin configuration/description -->
+        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver3"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/broken_device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: filter doesn't match Intents with action
+             android.app.action.DEVICE_ADMIN_ENABLED -->
+        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver4"
+                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_DISABLED" />
+            </intent-filter>
+        </receiver>
+
+        <!-- Broken device admin: no intent-filter -->
+        <receiver android:name="android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver5"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin" />
+        </receiver>
+
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/tests/deviceadmin/res/xml/broken_device_admin.xml b/tests/deviceadmin/res/xml/broken_device_admin.xml
new file mode 100644
index 0000000..937dabd
--- /dev/null
+++ b/tests/deviceadmin/res/xml/broken_device_admin.xml
@@ -0,0 +1,18 @@
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" />
+
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java
new file mode 100644
index 0000000..a8c5051
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminActivationTestActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+/**
+ * Helper {@link Activity} for CTS tests of Device Admin activation. The {@code Activity}
+ * enables tests to capture the invocations of its {@link #onActivityResult(int, int, Intent)} by
+ * providing a {@link OnActivityResultListener}.
+ */
+public class CtsDeviceAdminActivationTestActivity extends Activity {
+    public interface OnActivityResultListener {
+        void onActivityResult(int requestCode, int resultCode, Intent data);
+    }
+
+    private OnActivityResultListener mOnActivityResultListener;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Dismiss keyguard and keep screen on while this Activity is displayed.
+        // This is needed because on older platforms, when the keyguard is on, onActivityResult is
+        // not invoked when a Device Admin activation is rejected without user interaction.
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    public void setOnActivityResultListener(OnActivityResultListener listener) {
+        mOnActivityResultListener = listener;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (mOnActivityResultListener != null) {
+            mOnActivityResultListener.onActivityResult(requestCode, resultCode, data);
+            return;
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java
new file mode 100644
index 0000000..f64c6b6
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver extends DeviceAdminReceiver {
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java
new file mode 100644
index 0000000..492a7cb
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver2.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver2 extends DeviceAdminReceiver {
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java
new file mode 100644
index 0000000..92bc878
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver3.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver3 extends DeviceAdminReceiver {
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java
new file mode 100644
index 0000000..53f15a7
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver4.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver4 extends DeviceAdminReceiver {
+}
diff --git a/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java
new file mode 100644
index 0000000..2dc7100
--- /dev/null
+++ b/tests/deviceadmin/src/android/deviceadmin/cts/CtsDeviceAdminBrokenReceiver5.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 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.deviceadmin.cts;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class CtsDeviceAdminBrokenReceiver5 extends DeviceAdminReceiver {
+}
diff --git a/tests/tests/admin/Android.mk b/tests/tests/admin/Android.mk
index 1affed6..c3645cc 100644
--- a/tests/tests/admin/Android.mk
+++ b/tests/tests/admin/Android.mk
@@ -22,7 +22,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner mockito-target
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java b/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
new file mode 100644
index 0000000..2c7d7e9
--- /dev/null
+++ b/tests/tests/admin/src/android/admin/cts/DeviceAdminActivationTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2013 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.admin.cts;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver;
+import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver2;
+import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver3;
+import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver4;
+import android.deviceadmin.cts.CtsDeviceAdminBrokenReceiver5;
+import android.deviceadmin.cts.CtsDeviceAdminReceiver;
+import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity;
+import android.deviceadmin.cts.CtsDeviceAdminActivationTestActivity.OnActivityResultListener;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the standard way of activating a Device Admin: by starting system UI via an
+ * {@link Intent} with {@link DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}. The test requires that
+ * the {@code CtsDeviceAdmin.apk} be installed.
+ */
+public class DeviceAdminActivationTest
+    extends ActivityInstrumentationTestCase2<CtsDeviceAdminActivationTestActivity> {
+
+    // IMPLEMENTATION NOTE: Because Device Admin activation requires the use of
+    // Activity.startActivityForResult, this test creates an empty Activity which then invokes
+    // startActivityForResult.
+
+    private static final int REQUEST_CODE_ACTIVATE_ADMIN = 1;
+
+    /**
+     * Maximum duration of time (milliseconds) after which the effects of programmatic actions in
+     * this test should have affected the UI.
+     */
+    private static final int UI_EFFECT_TIMEOUT_MILLIS = 5000;
+
+    @Mock private OnActivityResultListener mMockOnActivityResultListener;
+
+    public DeviceAdminActivationTest() {
+        super(CtsDeviceAdminActivationTestActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        getActivity().setOnActivityResultListener(mMockOnActivityResultListener);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            finishActivateDeviceAdminActivity();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testActivateGoodReceiverDisplaysActivationUi() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminReceiver.class);
+        assertWithTimeoutOnActivityResultNotInvoked();
+        // The UI is up and running. Assert that dismissing the UI returns the corresponding result
+        // to the test activity.
+        finishActivateDeviceAdminActivity();
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    public void testActivateBrokenReceiverFails() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    public void testActivateBrokenReceiver2Fails() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver2.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    public void testActivateBrokenReceiver3Fails() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver3.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    public void testActivateBrokenReceiver4Fails() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver4.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    public void testActivateBrokenReceiver5Fails() throws Exception {
+        startAddDeviceAdminActivityForResult(CtsDeviceAdminBrokenReceiver5.class);
+        assertWithTimeoutOnActivityResultInvokedWithResultCode(Activity.RESULT_CANCELED);
+    }
+
+    private void startAddDeviceAdminActivityForResult(Class<?> receiverClass) {
+        getActivity().startActivityForResult(
+                getAddDeviceAdminIntent(receiverClass),
+                REQUEST_CODE_ACTIVATE_ADMIN);
+    }
+
+    private Intent getAddDeviceAdminIntent(Class<?> receiverClass) {
+        return new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
+            .putExtra(
+                    DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+                    new ComponentName(
+                            getInstrumentation().getTargetContext(),
+                            receiverClass));
+    }
+
+    private void assertWithTimeoutOnActivityResultNotInvoked() {
+        SystemClock.sleep(UI_EFFECT_TIMEOUT_MILLIS);
+        Mockito.verify(mMockOnActivityResultListener, Mockito.never())
+                .onActivityResult(
+                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
+                        Mockito.anyInt(),
+                        Mockito.any(Intent.class));
+    }
+
+    private void assertWithTimeoutOnActivityResultInvokedWithResultCode(int expectedResultCode) {
+        ArgumentCaptor<Integer> resultCodeCaptor = ArgumentCaptor.forClass(int.class);
+        Mockito.verify(mMockOnActivityResultListener, Mockito.timeout(UI_EFFECT_TIMEOUT_MILLIS))
+                .onActivityResult(
+                        Mockito.eq(REQUEST_CODE_ACTIVATE_ADMIN),
+                        resultCodeCaptor.capture(),
+                        Mockito.any(Intent.class));
+        assertEquals(expectedResultCode, (int) resultCodeCaptor.getValue());
+    }
+
+    private void finishActivateDeviceAdminActivity() {
+        getActivity().finishActivity(REQUEST_CODE_ACTIVATE_ADMIN);
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
index 6e6e6b2..914a0bc 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
@@ -242,7 +242,7 @@
         assertEquals(START_WIDTH, b.getWidth());
     }
 
-    public void testDecodeReuse1() throws IOException {
+    public void testDecodeReuseBasic() throws IOException {
         BitmapFactory.Options options = new BitmapFactory.Options();
         options.inMutable = true;
         options.inSampleSize = 0; // treated as 1
@@ -258,28 +258,24 @@
 
         assertEquals(originalSize, pass.getByteCount());
         assertEquals(originalSize, pass.getAllocationByteCount());
-        assertEquals(start, pass);
+        assertSame(start, pass);
         assertTrue(pass.isMutable());
     }
 
-    public void testDecodeReuse2() throws IOException {
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inMutable = true;
-        options.inScaled = false;
-        Bitmap original = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
-        int originalSize = original.getByteCount();
-        assertEquals(originalSize, original.getAllocationByteCount());
+    public void testDecodeReuseFormats() throws IOException {
+        // reuse should support all image formats
+        for (int i = 0; i < RES_IDS.length; ++i) {
+            Bitmap reuseBuffer = Bitmap.createBitmap(1000000, 1, Bitmap.Config.ALPHA_8);
 
-        options.inBitmap = original;
-        options.inSampleSize = 4;
-        Bitmap reduced = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
-
-        assertEquals(original, reduced);
-        assertEquals(originalSize, reduced.getAllocationByteCount());
-        assertEquals(originalSize, reduced.getByteCount() * 16);
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inBitmap = reuseBuffer;
+            options.inSampleSize = 5;
+            Bitmap decoded = BitmapFactory.decodeResource(mRes, RES_IDS[i], options);
+            assertSame(reuseBuffer, decoded);
+        }
     }
 
-    public void testDecodeReuse3() throws IOException {
+    public void testDecodeReuseFailure() throws IOException {
         BitmapFactory.Options options = new BitmapFactory.Options();
         options.inMutable = true;
         options.inScaled = false;
@@ -297,6 +293,63 @@
         assertTrue(failedCorrectly);
     }
 
+    public void testDecodeReuseScaling() throws IOException {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inMutable = true;
+        options.inScaled = false;
+        Bitmap original = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+        int originalSize = original.getByteCount();
+        assertEquals(originalSize, original.getAllocationByteCount());
+
+        options.inBitmap = original;
+        options.inSampleSize = 4;
+        Bitmap reduced = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+
+        assertSame(original, reduced);
+        assertEquals(originalSize, reduced.getAllocationByteCount());
+        assertEquals(originalSize, reduced.getByteCount() * 16);
+    }
+
+    public void testDecodeReuseDoubleScaling() throws IOException {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inMutable = true;
+        options.inScaled = false;
+        options.inSampleSize = 1;
+        Bitmap original = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+        int originalSize = original.getByteCount();
+
+        // Verify that inSampleSize and density scaling both work with reuse concurrently
+        options.inBitmap = original;
+        options.inScaled = true;
+        options.inSampleSize = 2;
+        options.inDensity = 2;
+        options.inTargetDensity = 4;
+        Bitmap doubleScaled = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+
+        assertSame(original, doubleScaled);
+        assertEquals(4, doubleScaled.getDensity());
+        assertEquals(originalSize, doubleScaled.getByteCount());
+    }
+
+    public void testDecodeReuseEquivalentScaling() throws IOException {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inMutable = true;
+        options.inScaled = true;
+        options.inDensity = 4;
+        options.inTargetDensity = 2;
+        Bitmap densityReduced = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+        assertEquals(2, densityReduced.getDensity());
+        options.inBitmap = densityReduced;
+        options.inDensity = 0;
+        options.inScaled = false;
+        options.inSampleSize = 2;
+        Bitmap scaleReduced = BitmapFactory.decodeResource(mRes, R.drawable.robot, options);
+        // verify that density isn't incorrectly carried over during bitmap reuse
+        assertFalse(densityReduced.getDensity() == 2);
+        assertFalse(densityReduced.getDensity() == 0);
+        assertSame(densityReduced, scaleReduced);
+    }
+
     private byte[] obtainArray() {
         ByteArrayOutputStream stm = new ByteArrayOutputStream();
         Options opt = new BitmapFactory.Options();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index 10a563c..8063cbb 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -63,7 +63,7 @@
         releaseHttpServer();
         super.tearDown();
     }
-/* disable the whole tests until someone could fix it.
+
     public void test_S0P0() throws Throwable {
         doPlayStreams(0, 0);
     }
@@ -91,7 +91,7 @@
     public void test_S6P00002() throws Throwable {
         doPlayStreams(6, 0.00002f);
     }
-*/
+
    private void doPlayStreams(int seed, float probability) throws Throwable {
         Random random = new Random(seed);
         createHttpServer(seed, probability);
@@ -309,8 +309,7 @@
                     try {
                         float random = mRandom.nextFloat();
                         if (random < probability) {
-                            // TODO restore 1000 to 6000 after fixing 6770717
-                            int sleepTimeMs = 1000 + mRandom.nextInt(500);
+                            int sleepTimeMs = 1000 + mRandom.nextInt(5000);
                             Thread.sleep(sleepTimeMs);
                             flush();
                         } else if (random < probability * 100) {
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 055b763..3cc71fa 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -412,7 +412,7 @@
     }
 
     public void testSetMaxFileSize() throws Exception {
-        if (!hasMicrophone()) {
+        if (!hasMicrophone() || !hasCamera()) {
             return;
         }
         testSetMaxFileSize(512 * 1024, 50 * 1024);
diff --git a/tests/tests/media/src/android/media/cts/TextureRender.java b/tests/tests/media/src/android/media/cts/TextureRender.java
index eb4236c..4125dcf 100644
--- a/tests/tests/media/src/android/media/cts/TextureRender.java
+++ b/tests/tests/media/src/android/media/cts/TextureRender.java
@@ -16,17 +16,17 @@
 
 package android.media.cts;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
 
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
+import android.graphics.Bitmap;
 import android.graphics.SurfaceTexture;
 import android.opengl.GLES11Ext;
 import android.opengl.GLES20;
-import android.opengl.GLSurfaceView;
 import android.opengl.Matrix;
 import android.util.Log;
 
@@ -44,9 +44,9 @@
     private final float[] mTriangleVerticesData = {
         // X, Y, Z, U, V
         -1.0f, -1.0f, 0, 0.f, 0.f,
-        1.0f, -1.0f, 0, 1.f, 0.f,
+         1.0f, -1.0f, 0, 1.f, 0.f,
         -1.0f,  1.0f, 0, 0.f, 1.f,
-        1.0f,  1.0f, 0, 1.f, 1.f,
+         1.0f,  1.0f, 0, 1.f, 1.f,
     };
 
     private FloatBuffer mTriangleVertices;
@@ -245,4 +245,58 @@
             throw new RuntimeException(op + ": glError " + error);
         }
     }
+
+    /**
+     * Saves the current frame to disk as a PNG image.  Frame starts from (0,0).
+     * <p>
+     * Useful for debugging.
+     */
+    public static void saveFrame(String filename, int width, int height) {
+        // glReadPixels gives us a ByteBuffer filled with what is essentially big-endian RGBA
+        // data (i.e. a byte of red, followed by a byte of green...).  We need an int[] filled
+        // with native-order ARGB data to feed to Bitmap.
+        //
+        // If we implement this as a series of buf.get() calls, we can spend 2.5 seconds just
+        // copying data around for a 720p frame.  It's better to do a bulk get() and then
+        // rearrange the data in memory.  (For comparison, the PNG compress takes about 500ms
+        // for a trivial frame.)
+        //
+        // So... we set the ByteBuffer to little-endian, which should turn the bulk IntBuffer
+        // get() into a straight memcpy on most Android devices.  Our ints will hold ABGR data.
+        // Swapping B and R gives us ARGB.  We need about 30ms for the bulk get(), and another
+        // 270ms for the color swap.
+        //
+        // Making this even more interesting is the upside-down nature of GL, which means we
+        // may want to flip the image vertically here.
+
+        ByteBuffer buf = ByteBuffer.allocateDirect(width * height * 4);
+        buf.order(ByteOrder.LITTLE_ENDIAN);
+        GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
+        buf.rewind();
+
+        int pixelCount = width * height;
+        int[] colors = new int[pixelCount];
+        buf.asIntBuffer().get(colors);
+        for (int i = 0; i < pixelCount; i++) {
+            int c = colors[i];
+            colors[i] = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16);
+        }
+
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(filename);
+            Bitmap bmp = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
+            bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
+            bmp.recycle();
+        } catch (IOException ioe) {
+            throw new RuntimeException("Failed to write file " + filename, ioe);
+        } finally {
+            try {
+                if (fos != null) fos.close();
+            } catch (IOException ioe2) {
+                throw new RuntimeException("Failed to close file " + filename, ioe2);
+            }
+        }
+        Log.d(TAG, "Saved " + width + "x" + height + " frame as '" + filename + "'");
+    }
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/WrapperTest.java b/tests/tests/opengl/src/android/opengl/cts/WrapperTest.java
index 7344b74..acc56fc 100644
--- a/tests/tests/opengl/src/android/opengl/cts/WrapperTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/WrapperTest.java
@@ -22,7 +22,6 @@
 import android.opengl.EGLDisplay;
 import android.opengl.EGLSurface;
 import android.opengl.GLES10;
-import android.opengl.GLES11Ext;
 import android.opengl.GLES20;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -41,8 +40,11 @@
     private EGLSurface mEGLSurface;
 
 
+    /**
+     * Tests range-checking on glGetIntegerv in GLES 1.x.
+     */
     public void testGetIntegerv1() {
-        eglSetup(1);
+        eglSetup(1, 1, 1);  // GLES 1.x with 1x1 pbuffer
 
         checkGlError("start");
 
@@ -91,11 +93,14 @@
             // good
         }
 
-        eglRelease();
+        eglRelease(true);
     }
 
+    /**
+     * Tests range-checking on glGetIntegerv in GLES 2.x.
+     */
     public void testGetIntegerv2() {
-        eglSetup(2);
+        eglSetup(2, 1, 1);  // GLES 2.x with 1x1 pbuffer
 
         checkGlError("start");
 
@@ -144,7 +149,52 @@
             // good
         }
 
-        eglRelease();
+        eglRelease(true);
+    }
+
+    /**
+     * Tests whether EGL is releasing resources when the thread exits.  If
+     * it doesn't, we'll consume memory rapidly, and will fail or be
+     * killed within a couple hundred iterations.
+     * <p>
+     * It may be worthwhile to watch the memory growth with procrank or showmap
+     * while the test runs to detect smaller leaks.
+     */
+    public void testThreadCleanup() throws Throwable {
+        class WrappedTest implements Runnable {
+            public Throwable mThrowable;
+
+            private static final int WIDTH = 1280;
+            private static final int HEIGHT = 720;
+
+            @Override
+            public void run() {
+                try {
+                    eglSetup(2, WIDTH, HEIGHT);
+                    if (!EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
+                        throw new RuntimeException("eglMakeCurrent failed");
+                    }
+                    eglRelease(false);
+                } catch (Throwable th) {
+                    mThrowable = th;
+                }
+            }
+        }
+
+        WrappedTest wrappedTest = new WrappedTest();
+
+        for (int i = 0; i < 1000; i++) {
+            if ((i % 25) == 0) {
+                Log.d(TAG, "iteration " + i);
+            }
+
+            Thread th = new Thread(wrappedTest, "EGL thrash");
+            th.start();
+            th.join();
+            if (wrappedTest.mThrowable != null) {
+                throw wrappedTest.mThrowable;
+            }
+        }
     }
 
     /**
@@ -158,11 +208,10 @@
         }
     }
 
-
     /**
      * Prepares EGL.  Pass in the desired GLES API version.
      */
-    private void eglSetup(int api) {
+    private void eglSetup(int api, int width, int height) {
         mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
         if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
             throw new RuntimeException("unable to get EGL14 display");
@@ -215,8 +264,8 @@
 
         // Create a 1x1 pbuffer surface
         int[] surfaceAttribs = {
-                EGL14.EGL_WIDTH, 1,
-                EGL14.EGL_HEIGHT, 1,
+                EGL14.EGL_WIDTH, width,
+                EGL14.EGL_HEIGHT, height,
                 EGL14.EGL_NONE
         };
         mEGLSurface = EGL14.eglCreatePbufferSurface(mEGLDisplay, configs[0], surfaceAttribs, 0);
@@ -232,10 +281,11 @@
     }
 
     /**
-     * Releases EGL goodies.
+     * Releases EGL goodies.  If switchCurrent is true, this will use eglMakeCurrent to switch
+     * away from the current surface+context before destroying them.
      */
-    private void eglRelease() {
-        if (EGL14.eglGetCurrentContext() == mEGLContext) {
+    private void eglRelease(boolean switchCurrent) {
+        if (switchCurrent) {
             // Clear the current context and surface to ensure they are discarded immediately.
             EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE,
                     EGL14.EGL_NO_CONTEXT);
diff --git a/tests/tests/provider/src/android/provider/cts/CalendarTest.java b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
index 3c10d0c..bd8e06d 100644
--- a/tests/tests/provider/src/android/provider/cts/CalendarTest.java
+++ b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
@@ -1965,6 +1965,10 @@
         assertTrue(eventId >= 0);
         return eventValues;
       }
+
+      public long getCalendarId() {
+        return mCalendarId;
+      }
     }
 
     /**
@@ -2000,7 +2004,8 @@
           CalendarContract.Instances.CONTENT_BY_DAY_URI, julianStart + "/" + julianEnd);
 
       // Query the range, sorting by event start time
-      Cursor c = mContentResolver.query(uri, null, null, null, Events.DTSTART);
+      Cursor c = mContentResolver.query(uri, null, Instances.CALENDAR_ID + "="
+              + helper.getCalendarId(), null, Events.DTSTART);
 
       // Assert that two events are returned
       assertEquals(c.getCount(), 2);
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 8acd0f4..17a109b 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -126,6 +126,7 @@
                     "45008",    // KT
                     "45005",    // SKT Mobility
                     "45002",     // SKT Mobility
+                    "45006",    // LGT
                     // Verizon
                     "310004",
                     "310012",
@@ -160,6 +161,7 @@
                     "30272",    // Rogers
                     "302370",   // Fido
                     "30237",    // Fido
+                    "45006",    // LGT
                     "45008"     // KT
             );
 
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 38f1ef4..5d846df 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -115,6 +115,12 @@
     plan = tools.TestPlan(packages)
     plan.Exclude(ptsPattern)
     plan.Exclude('android\.performance.*')
+    plan.Exclude('android\.media\.cts\.StreamingMediaPlayerTest.*')
+    # Test plan to not include media streaming tests
+    self.__WritePlan(plan, 'CTS-No-Media-Stream')
+
+    plan = tools.TestPlan(packages)
+    plan.Exclude('android\.performance.*')
     self.__WritePlan(plan, 'SDK')
 
     plan.Exclude(r'android\.tests\.sigtest')