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')