Merge "media: prepare for Codec 2.0" into pi-dev am: 9e4a3b8907
am: c4f52364eb
Change-Id: I921dbfbb075975cca1559d18986c283701d306ef
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 751766c..163aa62 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2751,9 +2751,9 @@
<string name="device_owner_disable_statusbar_test">Disable status bar</string>
<string name="device_owner_disable_statusbar_test_info">
Please press the below button to disable the status bar and verify that quick settings, notifications
- and the assist gesture are no longer available.\n
+ and the assistant gesture are no longer available.\n
Next, press the button to reenable the status bar and verify that quick settings, notification
- and the assist gesture are available again.\n
+ and the assistant gesture are available again.\n
Please mark the test accordingly.
</string>
<string name="device_owner_disable_statusbar_button">Disable status bar</string>
@@ -2765,7 +2765,7 @@
switch off the screen. Then press the power button to switch the screen back on and verify that
no keyguard was shown.\n
Next, press the button to reenable the keyguard and repeat the above steps, this time verifying that
- a keyguard was shown again.\n
+ a keyguard was shown.\n
Please mark the test accordingly.
</string>
<string name="device_owner_disable_keyguard_button">Disable keyguard</string>
@@ -2795,7 +2795,7 @@
button, etc., isn\'t shown.\n
6) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 7) The assist gesture isn\'t available.
+ 7) The assistant gesture isn\'t available.
</string>
<string name="device_owner_lock_task_ui_system_info_test">Enable system info</string>
<string name="device_owner_lock_task_ui_system_info_test_info">
@@ -2811,7 +2811,7 @@
button, etc., isn\'t shown.\n
6) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 7) The assist gesture isn\'t available.\n\n
+ 7) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_notifications_test">Enable notifications</string>
@@ -2828,7 +2828,7 @@
button, etc., isn\'t shown.\n
5) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 6) The assist gesture isn\'t available.\n\n
+ 6) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_home_test">Enable Home button</string>
@@ -2846,7 +2846,7 @@
button, etc., isn\'t shown.\n
6) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 7) The assist gesture isn\'t available.\n\n
+ 7) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_recents_test">Enable Overview button</string>
@@ -2863,7 +2863,7 @@
button, etc., isn\'t shown.\n
4) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 5) The assist gesture isn\'t available.\n\n
+ 5) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_global_actions_test">Enable global actions</string>
@@ -2881,7 +2881,7 @@
4) The Overview button is hidden and the Overview gesture (swipe-up) does not work.\n
5) Press the power button to turn off the screen, and press it again to turn the screen
back on. Lock screen shouldn\'t be shown.\n
- 6) The assist gesture isn\'t available.\n\n
+ 6) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_keyguard_test">Enable keyguard</string>
@@ -2898,7 +2898,7 @@
4) The Overview button is hidden and the Overview gesture (swipe-up) does not work.\n
5) Long-press the power button. The power button menu, which usually shows the power-off
button, etc., isn\'t shown.\n
- 6) The assist gesture isn\'t available.\n\n
+ 6) The assistant gesture isn\'t available.\n\n
Mark the test as \'pass\' only if ALL of the above requirements are met.
</string>
<string name="device_owner_lock_task_ui_stop_lock_task_test">Stop LockTask mode</string>
diff --git a/common/device-side/util/Android.mk b/common/device-side/util/Android.mk
index 931a493..8839465 100644
--- a/common/device-side/util/Android.mk
+++ b/common/device-side/util/Android.mk
@@ -36,6 +36,8 @@
LOCAL_SDK_VERSION := test_current
+LOCAL_JARJAR_RULES := $(LOCAL_PATH)/protobuf-jarjar-rules.txt
+
include $(BUILD_STATIC_JAVA_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/common/device-side/util/protobuf-jarjar-rules.txt b/common/device-side/util/protobuf-jarjar-rules.txt
new file mode 100644
index 0000000..9914809
--- /dev/null
+++ b/common/device-side/util/protobuf-jarjar-rules.txt
@@ -0,0 +1,3 @@
+rule com.google.protobuf.** com.google.compatibility.device.util.com.google.protobuf.@1
+rule android.**.nano.** com.google.compatibility.device.util.android.@1.nano.@2
+rule **.android.**.nano.** com.google.compatibility.device.util.@1.android.@2.nano.@3
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
index ce05ebf..3ef189a 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
@@ -62,6 +62,7 @@
"bionic",
"bluetooth",
"camera",
+ "deviceinfo",
"deqp",
"devtools",
"framework",
diff --git a/harness/tools/cts-tradefed/res/config/cts-known-failures.xml b/harness/tools/cts-tradefed/res/config/cts-known-failures.xml
index d7b92cd..8bf818e 100644
--- a/harness/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/harness/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -70,9 +70,6 @@
<option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withMobile" />
<option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintFails_withMobile" />
- <!-- b/62616944 -->
- <option name="compatibility:exclude-filter" value="CtsLibcoreJavaUtilCollectionsTestCases" />
-
<!-- b/18682315 -->
<option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_bind" />
<option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_simple" />
@@ -129,29 +126,9 @@
<option name="compatibility:exclude-filter" value="CtsVideoTestCases android.video.cts.VideoEncoderDecoderTest#testVp9Goog0Perf1280x0720" />
<option name="compatibility:exclude-filter" value="CtsVideoTestCases android.video.cts.VideoEncoderDecoderTest#testVp9Goog0Perf1920x1080" />
- <!-- b/37482372 -->
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowHistoryPreservePortraitTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInOutPortraitTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInitialHeaderOnBackPortraitTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInnerFragmentInOutPortraitTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#startWithFragmentAndInitTitleMultiWindowPortraitTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#startWithFragmentNoHeadersMultiWindowPortraitTest" />
-
<!-- b/63916274 -->
<option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.WiredHeadsetTest" />
- <!-- b/38177396 -->
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowHistoryPreserveLandscapeTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInOutLandscapeTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInitialHeaderOnBackLandscapeTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInnerFragmentInOutLandscapeTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#startWithFragmentAndInitTitleMultiWindowLandscapeTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#startWithFragmentNoHeadersMultiWindowLandscapeTest" />
-
- <!-- b/62924649 -->
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityLegacyFlowTest#legacyActivityMultiWindowTest" />
- <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityLegacyFlowTest#legacyActivityMultiWindowToggleTest" />
-
<!-- b/38224690 -->
<option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.NativeEncoderTest" />
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
index 7a62f09..545dcbe 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
@@ -33,7 +33,7 @@
../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
LOCAL_PACKAGE_NAME := CtsUsePermissionApp22
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
index 58ee1c7..3ab5ae3 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
@@ -31,7 +31,7 @@
../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
LOCAL_PACKAGE_NAME := CtsUsePermissionApp23
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp25/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp25/Android.mk
index 8528752..d8593cc 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp25/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp25/Android.mk
@@ -32,7 +32,7 @@
LOCAL_RESOURCE_DIR := cts/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res
LOCAL_PACKAGE_NAME := CtsUsePermissionApp25
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
index 52c8ba4..133abcf 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
@@ -31,7 +31,7 @@
LOCAL_RESOURCE_DIR := cts/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res
LOCAL_PACKAGE_NAME := CtsUsePermissionApp26
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk
index 3069bac..8ac2416 100644
--- a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk
+++ b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/Android.mk
@@ -20,12 +20,13 @@
LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-annotations android-support-test ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSyncInvalidAccountAuthorityTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
+
+LOCAL_SDK_VERSION := current
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/src/android/content/sync/cts/StubProvider.java b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/src/android/content/sync/cts/StubProvider.java
index f082cc8..c8343d4 100644
--- a/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/src/android/content/sync/cts/StubProvider.java
+++ b/hostsidetests/content/test-apps/CtsSyncInvalidAccountAuthorityTestCases/src/android/content/sync/cts/StubProvider.java
@@ -16,11 +16,11 @@
package android.content.sync.cts;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.net.Uri;
public class StubProvider extends ContentProvider {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ProfileTimeoutTestHelper.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ProfileTimeoutTestHelper.java
index a386baa..7af838a 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ProfileTimeoutTestHelper.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ProfileTimeoutTestHelper.java
@@ -29,7 +29,8 @@
*/
public class ProfileTimeoutTestHelper extends InstrumentationTestCase {
// This should be sufficiently smaller than ManagedProfileTest.PROFILE_TIMEOUT_DELAY_SEC.
- private static final int TIMEOUT_MS = 5_000;
+ // This should also be sufficiently larger than time required to run "input tap" on emulator.
+ private static final int TIMEOUT_MS = 30_000;
private static final ComponentName ADMIN_COMPONENT = new ComponentName(
BasicAdminReceiver.class.getPackage().getName(), BasicAdminReceiver.class.getName());
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index ef51156..0c783c5 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -94,6 +94,14 @@
protected static final int FLAG_EPHEMERAL = 0x00000100;
protected static final int FLAG_MANAGED_PROFILE = 0x00000020;
+ /**
+ * The {@link android.os.BatteryManager} flags value representing all charging types; {@link
+ * android.os.BatteryManager#BATTERY_PLUGGED_AC}, {@link
+ * android.os.BatteryManager#BATTERY_PLUGGED_USB}, and {@link
+ * android.os.BatteryManager#BATTERY_PLUGGED_WIRELESS}.
+ */
+ private static final int STAY_ON_WHILE_PLUGGED_IN_FLAGS = 7;
+
protected static interface Settings {
public static final String GLOBAL_NAMESPACE = "global";
public static interface Global {
@@ -155,6 +163,7 @@
removeTestUsers();
// Unlock keyguard before test
wakeupAndDismissKeyguard();
+ stayAwake();
// Go to home.
executeShellCommand("input keyevent KEYCODE_HOME");
}
@@ -887,6 +896,11 @@
executeShellCommand("wm dismiss-keyguard");
}
+ private void stayAwake() throws Exception {
+ executeShellCommand(
+ "settings put global stay_on_while_plugged_in " + STAY_ON_WHILE_PLUGGED_IN_FLAGS);
+ }
+
protected void startActivityAsUser(int userId, String packageName, String activityName)
throws Exception {
wakeupAndDismissKeyguard();
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index ace4fd1..6b0c7c2 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -85,7 +85,7 @@
private static final String PROFILE_CREDENTIAL = "1234";
// This should be sufficiently larger than ProfileTimeoutTestHelper.TIMEOUT_MS
- private static final int PROFILE_TIMEOUT_DELAY_MS = 10_000;
+ private static final int PROFILE_TIMEOUT_DELAY_MS = 40_000;
private int mParentUserId;
@@ -272,10 +272,12 @@
}
private void simulateUserInteraction(int timeMs) throws Exception {
+ final long endTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeMs);
final UserActivityEmulator helper = new UserActivityEmulator(getDevice());
- for (int i = 0; i < timeMs; i += timeMs/10) {
- Thread.sleep(timeMs/10);
+ while (System.nanoTime() < endTime) {
helper.tapScreenCenter();
+ // Just in case to prevent busy loop.
+ Thread.sleep(100);
}
}
diff --git a/hostsidetests/edi/AndroidTest.xml b/hostsidetests/edi/AndroidTest.xml
index aef3086..7823b7e 100644
--- a/hostsidetests/edi/AndroidTest.xml
+++ b/hostsidetests/edi/AndroidTest.xml
@@ -15,7 +15,7 @@
-->
<configuration description="Config for CTS EDI host test cases">
<option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="misc" />
+ <option name="config-descriptor:metadata" key="component" value="deviceinfo" />
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsEdiHostTestCases.jar" />
</test>
diff --git a/hostsidetests/edi/OWNERS b/hostsidetests/edi/OWNERS
new file mode 100644
index 0000000..73518d9
--- /dev/null
+++ b/hostsidetests/edi/OWNERS
@@ -0,0 +1,4 @@
+aaronholden@google.com
+agathaman@google.com
+nickrose@google.com
+samlin@google.com
diff --git a/hostsidetests/theme/assets/Q/260dpi.zip b/hostsidetests/theme/assets/Q/260dpi.zip
index 68423a4..eb94f3c 100644
--- a/hostsidetests/theme/assets/Q/260dpi.zip
+++ b/hostsidetests/theme/assets/Q/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/280dpi.zip b/hostsidetests/theme/assets/Q/280dpi.zip
index 9a09eb4..9c57432 100644
--- a/hostsidetests/theme/assets/Q/280dpi.zip
+++ b/hostsidetests/theme/assets/Q/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/300dpi.zip b/hostsidetests/theme/assets/Q/300dpi.zip
index 35390b9..813e89c 100644
--- a/hostsidetests/theme/assets/Q/300dpi.zip
+++ b/hostsidetests/theme/assets/Q/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/340dpi.zip b/hostsidetests/theme/assets/Q/340dpi.zip
index a65cc9f..63833a5 100644
--- a/hostsidetests/theme/assets/Q/340dpi.zip
+++ b/hostsidetests/theme/assets/Q/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/360dpi.zip b/hostsidetests/theme/assets/Q/360dpi.zip
index a7be2b6..990d536 100644
--- a/hostsidetests/theme/assets/Q/360dpi.zip
+++ b/hostsidetests/theme/assets/Q/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/400dpi.zip b/hostsidetests/theme/assets/Q/400dpi.zip
index f8e62bb..775799a 100644
--- a/hostsidetests/theme/assets/Q/400dpi.zip
+++ b/hostsidetests/theme/assets/Q/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/420dpi.zip b/hostsidetests/theme/assets/Q/420dpi.zip
index 3d70848..30caca6 100644
--- a/hostsidetests/theme/assets/Q/420dpi.zip
+++ b/hostsidetests/theme/assets/Q/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/560dpi.zip b/hostsidetests/theme/assets/Q/560dpi.zip
index e1527ed..5e5f00e 100644
--- a/hostsidetests/theme/assets/Q/560dpi.zip
+++ b/hostsidetests/theme/assets/Q/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/hdpi.zip b/hostsidetests/theme/assets/Q/hdpi.zip
index 59c6efc..4c5632b 100644
--- a/hostsidetests/theme/assets/Q/hdpi.zip
+++ b/hostsidetests/theme/assets/Q/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/ldpi.zip b/hostsidetests/theme/assets/Q/ldpi.zip
index 8e408af..cc056fc 100644
--- a/hostsidetests/theme/assets/Q/ldpi.zip
+++ b/hostsidetests/theme/assets/Q/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/mdpi.zip b/hostsidetests/theme/assets/Q/mdpi.zip
index 9aebe9d..334a0aa 100644
--- a/hostsidetests/theme/assets/Q/mdpi.zip
+++ b/hostsidetests/theme/assets/Q/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/tvdpi.zip b/hostsidetests/theme/assets/Q/tvdpi.zip
index 55525fb..ec20390 100644
--- a/hostsidetests/theme/assets/Q/tvdpi.zip
+++ b/hostsidetests/theme/assets/Q/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/xhdpi.zip b/hostsidetests/theme/assets/Q/xhdpi.zip
index 3fecabe..3de69ee 100644
--- a/hostsidetests/theme/assets/Q/xhdpi.zip
+++ b/hostsidetests/theme/assets/Q/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/xxhdpi.zip b/hostsidetests/theme/assets/Q/xxhdpi.zip
index 14d7680..cb43250 100644
--- a/hostsidetests/theme/assets/Q/xxhdpi.zip
+++ b/hostsidetests/theme/assets/Q/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Q/xxxhdpi.zip b/hostsidetests/theme/assets/Q/xxxhdpi.zip
index aa8d087..8a4f210 100644
--- a/hostsidetests/theme/assets/Q/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/Q/xxxhdpi.zip
Binary files differ
diff --git a/tests/JobScheduler/jobperm/Android.mk b/tests/JobScheduler/jobperm/Android.mk
index af892d9..2d519bb 100644
--- a/tests/JobScheduler/jobperm/Android.mk
+++ b/tests/JobScheduler/jobperm/Android.mk
@@ -20,6 +20,7 @@
LOCAL_MODULE_TAGS := tests
LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-annotations \
compatibility-device-util \
LOCAL_SRC_FILES := \
diff --git a/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java b/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java
index 5b3bac7..ef7463f 100644
--- a/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java
+++ b/tests/JobScheduler/jobperm/src/android/jobscheduler/cts/jobperm/JobPermProvider.java
@@ -16,8 +16,6 @@
package android.jobscheduler.cts.jobperm;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Intent;
@@ -25,6 +23,8 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import java.io.File;
import java.io.FileNotFoundException;
diff --git a/tests/framework/base/OWNERS b/tests/framework/base/OWNERS
new file mode 100644
index 0000000..fe4ebd7
--- /dev/null
+++ b/tests/framework/base/OWNERS
@@ -0,0 +1,9 @@
+# Windows & Activities
+ogunwale@google.com
+jjaggi@google.com
+racarr@google.com
+chaviw@google.com
+brycelee@google.com
+akulian@google.com
+roosa@google.com
+takaoka@google.com
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index 36be03a..29c516b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -204,7 +204,7 @@
mAmWmState.computeState(LAUNCHING_ACTIVITY);
mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true);
- mAmWmState.assertVisibility(BROADCAST_RECEIVER_ACTIVITY, false);
+ mAmWmState.assertNotExist(BROADCAST_RECEIVER_ACTIVITY);
}
@Test
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index c1c3cf0..27a0795 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -505,7 +505,7 @@
executeShellCommand("am broadcast -a " + TEST_ACTIVITY_ACTION_FINISH_SELF);
waitForDockNotMinimized();
- mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+ mAmWmState.assertNotExist(TEST_ACTIVITY);
assertDockNotMinimized();
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index 003f89b..4746117 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -229,7 +229,7 @@
// Lock the screen and ensure that the fullscreen activity showing over the lockscreen
// is visible, but not the PiP activity
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertKeyguardShowingAndOccluded();
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index e79c13b..67a773d 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -99,7 +99,7 @@
launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
mAmWmState.assertKeyguardShowingAndOccluded();
@@ -116,7 +116,7 @@
launchActivity(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY, true);
assertTrue(mAmWmState.getWmState().allWindowsVisible(
@@ -137,7 +137,8 @@
SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(
+ SHOW_WHEN_LOCKED_ACTIVITY, SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
@@ -154,7 +155,7 @@
launchActivity(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
assertWallpaperShowing();
@@ -173,7 +174,7 @@
mAmWmState.computeState(TEST_ACTIVITY, SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.assertVisibility(TEST_ACTIVITY, true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(true);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY, true);
mAmWmState.assertVisibility(TEST_ACTIVITY, false);
@@ -211,7 +212,7 @@
.setMultipleTask(false)
);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
mAmWmState.assertKeyguardShowingAndOccluded();
@@ -333,7 +334,8 @@
mAmWmState.assertSanity();
mAmWmState.assertHomeActivityVisible(false);
mAmWmState.assertKeyguardShowingAndNotOccluded();
- mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, false);
+ // The {@link SHOW_WHEN_LOCKED_ACTIVITY} has gone because of {@link pressBackButton()}.
+ mAmWmState.assertNotExist(SHOW_WHEN_LOCKED_ACTIVITY);
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
index 105121b..cdc115a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
@@ -16,6 +16,7 @@
package android.server.am;
+import static android.server.am.ActivityManagerState.STATE_STOPPED;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY;
@@ -102,7 +103,7 @@
public void testNewActivityDuringOccluded() throws Exception {
try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
launchActivity(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
assertEquals("Picked wrong transition", TRANSIT_ACTIVITY_OPEN,
@@ -134,10 +135,16 @@
mAmWmState.getWmState().getLastTransition());
assertSingleLaunch(SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY, logSeparator);
+ // Waiting for the standard keyguard since
+ // {@link SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY} called
+ // {@link Activity#showWhenLocked(boolean)} and removed the attribute.
lockScreenSession.gotoKeyguard();
logSeparator = separateLogs();
- launchActivity(SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY);
- mAmWmState.computeState(SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY);
+ // Waiting for {@link SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY} stopped since it
+ // already lost show-when-locked attribute.
+ launchActivityNoWait(SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY);
+ mAmWmState.waitForActivityState(
+ SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY, STATE_STOPPED);
assertSingleStartAndStop(SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY, logSeparator);
}
}
@@ -146,7 +153,7 @@
public void testNewActivityDuringOccludedWithAttr() throws Exception {
try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
- lockScreenSession.gotoKeyguard();
+ lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
launchActivity(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
mAmWmState.computeState(SHOW_WHEN_LOCKED_WITH_DIALOG_ACTIVITY);
assertEquals("Picked wrong transition", TRANSIT_ACTIVITY_OPEN,
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
index 11e1929..2d7beae 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
@@ -211,7 +211,7 @@
logE("***Waiting for debugger window failed");
}
- boolean waitForHomeActivityVisible() {
+ void waitForHomeActivityVisible() {
ComponentName homeActivity = mAmState.getHomeActivityName();
// Sometimes this function is called before we know what Home Activity is
if (homeActivity == null) {
@@ -221,20 +221,15 @@
}
assertNotNull("homeActivity should not be null", homeActivity);
waitForValidState(homeActivity);
- return mAmState.isHomeActivityVisible();
}
- /**
- * @return true if recents activity is visible. Devices without recents will return false
- */
- boolean waitForRecentsActivityVisible() {
+ void waitForRecentsActivityVisible() {
if (mAmState.isHomeRecentsComponent()) {
- return waitForHomeActivityVisible();
+ waitForHomeActivityVisible();
+ } else {
+ waitForWithAmState(ActivityManagerState::isRecentsActivityVisible,
+ "***Waiting for recents activity to be visible...");
}
-
- waitForWithAmState(ActivityManagerState::isRecentsActivityVisible,
- "***Waiting for recents activity to be visible...");
- return mAmState.isRecentsActivityVisible();
}
void waitForKeyguardShowingAndNotOccluded() {
@@ -573,15 +568,26 @@
assertEquals(msg, windowName, mWmState.getFrontWindow());
}
+ void assertNotExist(final ComponentName activityName) {
+ final String windowName = getWindowName(activityName);
+ assertFalse("Activity=" + getActivityName(activityName) + " must NOT exist.",
+ mAmState.containsActivity(activityName));
+ assertFalse("Window=" + windowName + " must NOT exits.",
+ mWmState.containsWindow(windowName));
+ }
+
public void assertVisibility(final ComponentName activityName, final boolean visible) {
final String windowName = getWindowName(activityName);
- final boolean activityVisible = mAmState.isActivityVisible(activityName);
- final boolean windowVisible = mWmState.isWindowVisible(windowName);
+ // Check existence of activity and window.
+ assertTrue("Activity=" + getActivityName(activityName) + " must exist.",
+ mAmState.containsActivity(activityName));
+ assertTrue("Window=" + windowName + " must exist.", mWmState.containsWindow(windowName));
+ // Check visibility of activity and window.
assertEquals("Activity=" + getActivityName(activityName) + " must" + (visible ? "" : " NOT")
- + " be visible.", visible, activityVisible);
+ + " be visible.", visible, mAmState.isActivityVisible(activityName));
assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT") + " be visible.",
- visible, windowVisible);
+ visible, mWmState.isWindowVisible(windowName));
}
void assertHomeActivityVisible(boolean visible) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index e187eee..9b99471 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -74,14 +74,13 @@
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
-import android.graphics.Bitmap;
import android.content.Intent;
+import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.server.am.settings.SettingsSession;
import android.support.test.InstrumentationRegistry;
-
import android.support.test.rule.ActivityTestRule;
import com.android.compatibility.common.util.SystemUtil;
@@ -685,13 +684,17 @@
return this;
}
- public LockScreenSession gotoKeyguard() {
+ public LockScreenSession gotoKeyguard(ComponentName... showWhenLockedActivities) {
if (DEBUG && isLockDisabled()) {
logE("LockScreenSession.gotoKeyguard() is called without lock enabled.");
}
sleepDevice();
wakeUpDevice();
- mAmWmState.waitForKeyguardShowingAndNotOccluded();
+ if (showWhenLockedActivities.length == 0) {
+ mAmWmState.waitForKeyguardShowingAndNotOccluded();
+ } else {
+ mAmWmState.waitForValidState(showWhenLockedActivities);
+ }
return this;
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
index ae9c5b5..1171c18 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsTests.java
@@ -22,6 +22,12 @@
import static android.server.wm.alertwindowapp.Components.ALERT_WINDOW_TEST_ACTIVITY;
import static android.server.wm.alertwindowappsdk25.Components.SDK25_ALERT_WINDOW_TEST_ACTIVITY;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -150,13 +156,12 @@
// in place for SYSTEM_ALERT_WINDOW, which allows the window
// to be created, but will be hidden instead.
if (isUiModeLockedToVrHeadset()) {
- assertTrue("Should not be empty alertWindows=" + alertWindows,
- !alertWindows.isEmpty());
+ assertThat("Should not be empty alertWindows",
+ alertWindows, hasSize(greaterThan(0)));
assertTrue("All alert windows should be hidden",
allWindowsHidden(alertWindows));
} else {
- assertTrue("Should be empty alertWindows=" + alertWindows,
- alertWindows.isEmpty());
+ assertThat("Should be empty alertWindows", alertWindows, empty());
assertTrue(AppOpsUtils.rejectedOperationLogged(packageName,
OPSTR_SYSTEM_ALERT_WINDOW));
return;
@@ -166,8 +171,8 @@
if (atLeastO) {
// Assert that only TYPE_APPLICATION_OVERLAY was created.
for (WindowManagerState.WindowState win : alertWindows) {
- assertTrue("Can't create win=" + win + " on SDK O or greater",
- win.getType() == TYPE_APPLICATION_OVERLAY);
+ assertEquals("Can't create win=" + win + " on SDK O or greater",
+ win.getType(), TYPE_APPLICATION_OVERLAY);
}
}
@@ -181,17 +186,17 @@
alertWindows.get(alertWindows.size() - 1);
// Assert that the alert windows have higher z-order than the main app window
- assertTrue("lowestAlertWindow=" + lowestAlertWindow + " less than mainAppWindow="
- + mainAppWindow,
- wmState.getZOrder(lowestAlertWindow) > wmState.getZOrder(mainAppWindow));
+ assertThat("lowestAlertWindow has higher z-order than mainAppWindow",
+ wmState.getZOrder(lowestAlertWindow),
+ greaterThan(wmState.getZOrder(mainAppWindow)));
// Assert that legacy alert windows have a lower z-order than the new alert window layer.
final WindowManagerState.WindowState appOverlayWindow =
wmState.getWindowByPackageName(packageName, TYPE_APPLICATION_OVERLAY);
if (appOverlayWindow != null && highestAlertWindow != appOverlayWindow) {
- assertTrue("highestAlertWindow=" + highestAlertWindow
- + " greater than appOverlayWindow=" + appOverlayWindow,
- wmState.getZOrder(highestAlertWindow) < wmState.getZOrder(appOverlayWindow));
+ assertThat("highestAlertWindow has lower z-order than appOverlayWindow",
+ wmState.getZOrder(highestAlertWindow),
+ lessThan(wmState.getZOrder(appOverlayWindow)));
}
// Assert that alert windows are below key system windows.
@@ -199,9 +204,9 @@
wmState.getWindowsByPackageName(packageName, SYSTEM_WINDOW_TYPES);
if (!systemWindows.isEmpty()) {
final WindowManagerState.WindowState lowestSystemWindow = alertWindows.get(0);
- assertTrue("highestAlertWindow=" + highestAlertWindow
- + " greater than lowestSystemWindow=" + lowestSystemWindow,
- wmState.getZOrder(highestAlertWindow) < wmState.getZOrder(lowestSystemWindow));
+ assertThat("highestAlertWindow has lower z-order than lowestSystemWindow",
+ wmState.getZOrder(highestAlertWindow),
+ lessThan(wmState.getZOrder(lowestSystemWindow)));
}
assertTrue(AppOpsUtils.allowedOperationLogged(packageName, OPSTR_SYSTEM_ALERT_WINDOW));
}
diff --git a/tests/libcore/javautilcollections/Android.mk b/tests/libcore/javautilcollections/Android.mk
deleted file mode 100644
index 5a0bbb9..0000000
--- a/tests/libcore/javautilcollections/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2016 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 := guava-20.0-prebuilt
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_SRC_FILES := libs/guava-20.0.jar
-LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_SDK_VERSION := current
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := guava-testlib-20.0-prebuilt
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_SRC_FILES := libs/guava-testlib-20.0.jar
-LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_SDK_VERSION := current
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := \
- ctstestrunner \
- guava-20.0-prebuilt \
- guava-testlib-20.0-prebuilt
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsLibcoreJavaUtilCollectionsTestCases
-LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/libcore/javautilcollections/AndroidManifest.xml b/tests/libcore/javautilcollections/AndroidManifest.xml
deleted file mode 100644
index a7e8cee..0000000
--- a/tests/libcore/javautilcollections/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2016 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="libcore.java.util.collectiontests">
-
- <!-- AndroidJUnitRunner needs a largeHeap to collect the ~ 240k test methods to run. -->
- <application android:largeHeap="true">
- <uses-library android:name="android.test.runner"/>
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="libcore.java.util.collectiontests"
- android:label="Tests for Collection implementations in java.util">
- </instrumentation>
-
-</manifest>
-
diff --git a/tests/libcore/javautilcollections/AndroidTest.xml b/tests/libcore/javautilcollections/AndroidTest.xml
deleted file mode 100644
index 7ea7634..0000000
--- a/tests/libcore/javautilcollections/AndroidTest.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-<configuration description="Config for CTS Libcore java.util Collection test cases">
- <option name="test-suite-tag" value="cts" />
- <option name="not-shardable" value="true" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreJavaUtilCollectionsTestCases.apk" />
- </target_preparer>
- <!--
- Notes as of November 2016:
-
- 1.) When the runner collects the set of tests to run, it
- (a) attempts to directly run TestCase subclasses from guava-testlib, which they don't support,
- (b) doesn't find classes with suite() methods.
- (c) runs out of memory if attempting to run all of the > 220k tests in a single go
- Breaking the tests down into chunks of ~ 40-50k tests each, and explicitly specifying the
- suites to run, solves these problems.
-
- 2.) Due to http://b/33068110 the classes with the suite() methods (in the "suite" sub-package)
- need to extend TestSuite, which means that they need to delegate to separate classes (in the
- "tests" sub-package) that extend classes from guava-testlib.
- -->
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="libcore.java.util.collectiontests" />
- <option name="class" value="libcore.java.util.suite.ConcurrentSkipListMapNaturalSuite" />
- <option name="runtime-hint" value="10m" />
- <option name="test-timeout" value="1200000" />
- <option name="shell-timeout" value="1400000" />
- </test>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="libcore.java.util.collectiontests" />
- <option name="class" value="libcore.java.util.suite.ConcurrentSkipListMapWithComparatorSuite" />
- <option name="runtime-hint" value="10m" />
- <option name="test-timeout" value="1200000" />
- <option name="shell-timeout" value="1400000" />
- </test>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="libcore.java.util.collectiontests" />
- <option name="class" value="libcore.java.util.suite.TreeMapNaturalSuite" />
- <option name="runtime-hint" value="10m" />
- <option name="test-timeout" value="1200000" />
- <option name="shell-timeout" value="1400000" />
- </test>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="libcore.java.util.collectiontests" />
- <option name="class" value="libcore.java.util.suite.TreeMapWithComparatorSuite" />
- <option name="runtime-hint" value="10m" />
- <option name="test-timeout" value="1200000" />
- <option name="shell-timeout" value="1400000" />
- </test>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="libcore.java.util.collectiontests" />
- <option name="class" value="libcore.java.util.suite.OtherCollectionsSuite" />
- <option name="runtime-hint" value="8m" />
- <option name="test-timeout" value="1200000" />
- <option name="shell-timeout" value="1400000" />
- </test>
-</configuration>
diff --git a/tests/libcore/javautilcollections/libs/guava-20.0.jar b/tests/libcore/javautilcollections/libs/guava-20.0.jar
deleted file mode 100644
index 632772f..0000000
--- a/tests/libcore/javautilcollections/libs/guava-20.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar b/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar
deleted file mode 100644
index 6dd8d90..0000000
--- a/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar
+++ /dev/null
Binary files differ
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java
deleted file mode 100644
index 332190b..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.suite;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
-
-public class ConcurrentSkipListMapNaturalSuite extends TestSuite {
- public static Test suite() {
- return new AndroidTestsForMapsInJavaUtil(MapsToTest.CONCURRENT_SKIP_LIST_MAP_NATURAL)
- .allTests();
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java
deleted file mode 100644
index 878e721..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.suite;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
-
-public class ConcurrentSkipListMapWithComparatorSuite extends TestSuite {
- public static Test suite() {
- return new AndroidTestsForMapsInJavaUtil(
- MapsToTest.CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR).allTests();
- }
-
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java
deleted file mode 100644
index 6af45f4..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.suite;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import libcore.java.util.tests.AndroidTestsForListsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
-import libcore.java.util.tests.AndroidTestsForQueuesInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForSetsInJavaUtil;
-
-/**
- * A suite of all guava-testlib Collection tests not covered by the other suites in this
- * package.
- */
-public class OtherCollectionsSuite extends TestSuite {
- public static Test suite() {
- TestSuite result = new TestSuite();
- result.addTest(new AndroidTestsForListsInJavaUtil().allTests());
- result.addTest(new AndroidTestsForMapsInJavaUtil(MapsToTest.OTHER).allTests());
- result.addTest(new AndroidTestsForQueuesInJavaUtil().allTests());
- result.addTest(new AndroidTestsForSetsInJavaUtil().allTests());
- return result;
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java
deleted file mode 100644
index 68a7624..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.suite;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
-
-public class TreeMapNaturalSuite extends TestSuite {
- public static Test suite() {
- return new AndroidTestsForMapsInJavaUtil(MapsToTest.TREE_MAP_NATURAL).allTests();
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java
deleted file mode 100644
index 6e6fd6f..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.suite;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
-import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
-
-public class TreeMapWithComparatorSuite extends TestSuite {
- public static Test suite() {
- return new AndroidTestsForMapsInJavaUtil(MapsToTest.TREE_MAP_WITH_COMPARATOR).allTests();
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java
deleted file mode 100644
index 8d9177c..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.tests;
-
-import com.google.common.collect.testing.TestsForListsInJavaUtil;
-import com.google.common.collect.testing.testers.CollectionToArrayTester;
-
-import junit.framework.Test;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * Guava-testlib tests for {@code List} implementations from {@code java.util}.
- */
-public class AndroidTestsForListsInJavaUtil extends TestsForListsInJavaUtil {
- @Override
- protected Collection<Method> suppressForArraysAsList() {
- return Collections.singleton(
- // http://b/30829421
- CollectionToArrayTester.getToArrayIsPlainObjectArrayMethod());
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java
deleted file mode 100644
index 11f0afe..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.tests;
-
-import com.google.common.collect.testing.TestsForMapsInJavaUtil;
-import com.google.common.collect.testing.testers.CollectionAddAllTester;
-import com.google.common.collect.testing.testers.CollectionAddTester;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * Guava-testlib tests for {@link MapsToTest} that were specified as a
- * constructor argument.
- */
-public class AndroidTestsForMapsInJavaUtil extends TestsForMapsInJavaUtil {
- public enum MapsToTest {
- /** All Maps other than those below. */
- OTHER,
- /** TreeMao with natural ordering. */
- TREE_MAP_NATURAL,
- /** TreeMap with a Comparator. */
- TREE_MAP_WITH_COMPARATOR,
- /** ConcurrentSKipListMap with natural ordering. */
- CONCURRENT_SKIP_LIST_MAP_NATURAL,
- /** ConcurrentSKipListMap with a Comparator. */
- CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR
- }
-
- private final MapsToTest mapsToTest;
-
- public AndroidTestsForMapsInJavaUtil(MapsToTest mapsToTest) {
- this.mapsToTest = Objects.requireNonNull(mapsToTest);
- }
-
- /**
- * Returns the tests for the {@link MapsToTest} from {@code java.util}.
- */
- @Override
- public final Test allTests() {
- TestSuite suite = new TestSuite("java.util Maps: " + mapsToTest);
- switch (mapsToTest) {
- case OTHER:
- suite.addTest(testsForCheckedMap());
- suite.addTest(testsForCheckedSortedMap());
- suite.addTest(testsForEmptyMap());
- suite.addTest(testsForSingletonMap());
- suite.addTest(testsForHashMap());
- suite.addTest(testsForLinkedHashMap());
- suite.addTest(testsForEnumMap());
- suite.addTest(testsForConcurrentHashMap());
- break;
- case TREE_MAP_NATURAL:
- suite.addTest(testsForTreeMapNatural());
- break;
- case TREE_MAP_WITH_COMPARATOR:
- suite.addTest(testsForTreeMapWithComparator());
- break;
- case CONCURRENT_SKIP_LIST_MAP_NATURAL:
- suite.addTest(testsForConcurrentSkipListMapNatural());
- break;
- case CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR:
- suite.addTest(testsForConcurrentSkipListMapWithComparator());
- break;
- default:
- throw new IllegalArgumentException("Unknown part: " + mapsToTest);
- }
- return suite;
- }
-
- @Override
- protected final Collection<Method> suppressForConcurrentHashMap() {
- // http://b/30853241
- return Arrays.asList(
- CollectionAddAllTester.getAddAllUnsupportedNonePresentMethod(),
- CollectionAddAllTester.getAddAllUnsupportedSomePresentMethod(),
- CollectionAddTester.getAddUnsupportedNotPresentMethod());
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java
deleted file mode 100644
index 52f0eb3..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.tests;
-
-import com.google.common.collect.testing.MinimalCollection;
-import com.google.common.collect.testing.QueueTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringQueueGenerator;
-import com.google.common.collect.testing.TestsForListsInJavaUtil;
-import com.google.common.collect.testing.TestsForQueuesInJavaUtil;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.LinkedList;
-import java.util.Queue;
-import junit.framework.Test;
-
-/**
- * Guava-testlib tests for {@code Queue} implementations from {@code java.util}.
- */
-public class AndroidTestsForQueuesInJavaUtil extends TestsForQueuesInJavaUtil {
-
- /**
- * Override and copy the super class's implementation in order to change the name to ensure
- * that created tests are unique and do not clash with those created by
- * {@link TestsForListsInJavaUtil#testsForLinkedList()}, see bug 62438629.
- */
- @Override
- public Test testsForLinkedList() {
- return QueueTestSuiteBuilder.using(
- new TestStringQueueGenerator() {
- @Override
- public Queue<String> create(String[] elements) {
- return new LinkedList<String>(MinimalCollection.of(elements));
- }
- })
- .named("LinkedList as Queue")
- .withFeatures(
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .skipCollectionTests() // already covered in TestsForListsInJavaUtil
- .suppressing(suppressForLinkedList())
- .createTestSuite();
- }
-}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java
deleted file mode 100644
index c4e41f4..0000000
--- a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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 libcore.java.util.tests;
-
-import com.google.common.collect.testing.TestsForSetsInJavaUtil;
-
-import junit.framework.Test;
-
-/**
- * Guava-testlib tests for {@code Set} implementations from {@code java.util}.
- */
-public class AndroidTestsForSetsInJavaUtil extends TestsForSetsInJavaUtil {
-}
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
index 8a5e974..d4f844f 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
@@ -368,6 +368,33 @@
}
@Test
+ public void testSeekAfterPause() throws Throwable {
+ final AnimatorSet set = new AnimatorSet();
+ ValueAnimator a1 = ValueAnimator.ofFloat(0f, 50f);
+ a1.setDuration(50);
+ ValueAnimator a2 = ValueAnimator.ofFloat(50, 100f);
+ a2.setDuration(50);
+ set.playSequentially(a1, a2);
+ set.setInterpolator(new LinearInterpolator());
+
+ mActivityRule.runOnUiThread(() -> {
+ set.start();
+ set.pause();
+ set.setCurrentPlayTime(60);
+ assertEquals((long) set.getCurrentPlayTime(), 60);
+ assertEquals((float) a1.getAnimatedValue(), 50f, EPSILON);
+ assertEquals((float) a2.getAnimatedValue(), 60f, EPSILON);
+
+ set.setCurrentPlayTime(40);
+ assertEquals((long) set.getCurrentPlayTime(), 40);
+ assertEquals((float) a1.getAnimatedValue(), 40f, EPSILON);
+ assertEquals((float) a2.getAnimatedValue(), 50f, EPSILON);
+
+ set.cancel();
+ });
+ }
+
+ @Test
public void testDuration() throws Throwable {
xAnimator.setRepeatCount(ValueAnimator.INFINITE);
Animator[] animatorArray = { xAnimator, yAnimator };
diff --git a/tests/tests/content/Android.mk b/tests/tests/content/Android.mk
index dc2c253..85097a1 100644
--- a/tests/tests/content/Android.mk
+++ b/tests/tests/content/Android.mk
@@ -56,7 +56,8 @@
-c tlh \
-c xx,xx-rYY
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-Iaidl-files-under, BinderPermissionTestService)
LOCAL_MULTILIB := both
LOCAL_PACKAGE_NAME := CtsContentTestCases
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index 20baa2d..a4e5b1f 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -144,9 +144,9 @@
<uses-library android:name="android.test.runner" />
- <service android:name="android.content.cts.MockContextWrapperService" />
- <activity android:name=".content.ContextWrapperCtsActivity"
- android:label="ContextWrapperCtsActivity">
+ <service android:name="android.content.cts.MockContextService" />
+ <activity android:name=".content.ContextCtsActivity"
+ android:label="ContextCtsActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
@@ -167,7 +167,7 @@
<intent-filter android:priority="1">
<action android:name="android.content.cts.BroadcastReceiverTest.BROADCAST_MOCKTEST" />
<action android:name="android.content.cts.BroadcastReceiverTest.BROADCAST_TESTABORT" />
- <action android:name="android.content.cts.ContextWrapperTest.BROADCAST_TESTORDER" />
+ <action android:name="android.content.cts.ContextTest.BROADCAST_TESTORDER" />
</intent-filter>
</receiver>
@@ -189,7 +189,8 @@
<!--Test for PackageManager-->
<activity android:name="android.content.pm.cts.TestPmActivity"
- android:icon="@drawable/start">
+ android:icon="@drawable/start"
+ android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.PMTEST" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -203,7 +204,8 @@
</intent-filter>
</activity>
<!--Test for PackageManager-->
- <service android:name="android.content.pm.cts.TestPmService">
+ <service android:name="android.content.pm.cts.TestPmService"
+ android:permission="android.content.cts.CALL_ABROAD_PERMISSION">
<intent-filter>
<action android:name="android.content.pm.cts.activity.PMTEST_SERVICE" />
</intent-filter>
diff --git a/tests/tests/content/AndroidTest.xml b/tests/tests/content/AndroidTest.xml
index 58305dd..7b7f52e 100644
--- a/tests/tests/content/AndroidTest.xml
+++ b/tests/tests/content/AndroidTest.xml
@@ -32,6 +32,7 @@
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsContentTestCases.apk" />
<option name="test-file-name" value="CtsSyncAccountAccessStubs.apk" />
+ <option name="test-file-name" value="CtsBinderPermissionTestService.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/tests/content/BinderPermissionTestService/Android.mk b/tests/tests/content/BinderPermissionTestService/Android.mk
new file mode 100644
index 0000000..697d8f6
--- /dev/null
+++ b/tests/tests/content/BinderPermissionTestService/Android.mk
@@ -0,0 +1,36 @@
+#
+# Copyright (C) 2018 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_SDK_VERSION := current
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-Iaidl-files-under, aidl)
+
+LOCAL_PACKAGE_NAME := CtsBinderPermissionTestService
+
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/content/BinderPermissionTestService/AndroidManifest.xml b/tests/tests/content/BinderPermissionTestService/AndroidManifest.xml
new file mode 100644
index 0000000..c0e4774
--- /dev/null
+++ b/tests/tests/content/BinderPermissionTestService/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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">
+ <application>
+ <service
+ android:name=".BinderPermissionTestService"
+ android:exported="true">
+ </service>
+ </application>
+</manifest>
diff --git a/tests/tests/content/BinderPermissionTestService/README.txt b/tests/tests/content/BinderPermissionTestService/README.txt
new file mode 100644
index 0000000..1b7c2bd
--- /dev/null
+++ b/tests/tests/content/BinderPermissionTestService/README.txt
@@ -0,0 +1,7 @@
+A test project that publishes a Binder service. The methods of this service
+check if their caller has certain permissions. This service is used by
+Context tests to verify that methods like enforceCallingPermission()
+work correctly.
+
+This service has to be in a separate package so the permissions of the
+caller (the test) and the callee (this service) are different.
diff --git a/tests/tests/content/BinderPermissionTestService/aidl/com/android/cts/IBinderPermissionTestService.aidl b/tests/tests/content/BinderPermissionTestService/aidl/com/android/cts/IBinderPermissionTestService.aidl
new file mode 100644
index 0000000..26e6326
--- /dev/null
+++ b/tests/tests/content/BinderPermissionTestService/aidl/com/android/cts/IBinderPermissionTestService.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 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;
+
+interface IBinderPermissionTestService {
+ // Methods that, when called, invoke one of the permission check methods
+ // to check the caller's permissions.
+ void doEnforceCallingPermission(String permission);
+ int doCheckCallingPermission(String permission);
+ void doEnforceCallingOrSelfPermission(String permission);
+ int doCheckCallingOrSelfPermission(String permission);
+}
diff --git a/tests/tests/content/BinderPermissionTestService/src/com/android/cts/BinderPermissionTestService.java b/tests/tests/content/BinderPermissionTestService/src/com/android/cts/BinderPermissionTestService.java
new file mode 100644
index 0000000..955fb30
--- /dev/null
+++ b/tests/tests/content/BinderPermissionTestService/src/com/android/cts/BinderPermissionTestService.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+public class BinderPermissionTestService extends Service {
+
+ private static String TEST_NOT_ALLOWED_MESSAGE = "Test: you're not allowed to do this.";
+
+ private final IBinder mBinder = new IBinderPermissionTestService.Stub() {
+ @Override
+ public void doEnforceCallingPermission(String permission) {
+ enforceCallingPermission(permission, TEST_NOT_ALLOWED_MESSAGE);
+ }
+
+ @Override
+ public int doCheckCallingPermission(String permission) {
+ return checkCallingPermission(permission);
+ }
+
+ @Override
+ public void doEnforceCallingOrSelfPermission(String permission) {
+ enforceCallingOrSelfPermission(permission, TEST_NOT_ALLOWED_MESSAGE);
+ }
+
+ @Override
+ public int doCheckCallingOrSelfPermission(String permission) {
+ return checkCallingOrSelfPermission(permission);
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+}
diff --git a/tests/tests/content/SyncAccountAccessStubs/Android.mk b/tests/tests/content/SyncAccountAccessStubs/Android.mk
index 9f015a3..d176ce7 100644
--- a/tests/tests/content/SyncAccountAccessStubs/Android.mk
+++ b/tests/tests/content/SyncAccountAccessStubs/Android.mk
@@ -20,10 +20,13 @@
LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-annotations
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSyncAccountAccessStubs
-LOCAL_PRIVATE_PLATFORM_APIS := true
+
+LOCAL_SDK_VERSION := current
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/tests/tests/content/SyncAccountAccessStubs/src/com/android/cts/stub/StubProvider.java b/tests/tests/content/SyncAccountAccessStubs/src/com/android/cts/stub/StubProvider.java
index 8a21e0d..c97e115 100644
--- a/tests/tests/content/SyncAccountAccessStubs/src/com/android/cts/stub/StubProvider.java
+++ b/tests/tests/content/SyncAccountAccessStubs/src/com/android/cts/stub/StubProvider.java
@@ -16,12 +16,12 @@
package com.android.cts.stub;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
public class StubProvider extends ContentProvider {
@Override
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java b/tests/tests/content/src/android/content/cts/ContextCtsActivity.java
similarity index 94%
rename from tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java
rename to tests/tests/content/src/android/content/cts/ContextCtsActivity.java
index 7ea2ab7..a7ea89a 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperCtsActivity.java
+++ b/tests/tests/content/src/android/content/cts/ContextCtsActivity.java
@@ -23,7 +23,7 @@
import android.content.cts.R;
-public class ContextWrapperCtsActivity extends Activity {
+public class ContextCtsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index f84c771..413da63 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -16,39 +16,131 @@
package android.content.cts;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Resources.NotFoundException;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
+import android.database.sqlite.SQLiteCursorDriver;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQuery;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
+import android.os.Process;
+import android.preference.PreferenceManager;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import android.view.WindowManager;
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.cts.IBinderPermissionTestService;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class ContextTest extends AndroidTestCase {
private static final String TAG = "ContextTest";
+ private static final String ACTUAL_RESULT = "ResultSetByReceiver";
- private Context mContext;
+ private static final String INTIAL_RESULT = "IntialResult";
+
+ private static final String VALUE_ADDED = "ValueAdded";
+ private static final String KEY_ADDED = "AddedByReceiver";
+
+ private static final String VALUE_REMOVED = "ValueWillBeRemove";
+ private static final String KEY_REMOVED = "ToBeRemoved";
+
+ private static final String VALUE_KEPT = "ValueKept";
+ private static final String KEY_KEPT = "ToBeKept";
+
+ private static final String MOCK_STICKY_ACTION = "android.content.cts.ContextTest."
+ + "STICKY_BROADCAST_RESULT";
+
+ private static final String ACTION_BROADCAST_TESTORDER =
+ "android.content.cts.ContextTest.BROADCAST_TESTORDER";
+ private final static String MOCK_ACTION1 = ACTION_BROADCAST_TESTORDER + "1";
+ private final static String MOCK_ACTION2 = ACTION_BROADCAST_TESTORDER + "2";
+
+ // Note: keep these constants in sync with the permissions used by BinderPermissionTestService.
+ //
+ // A permission that's granted to this test package.
+ public static final String GRANTED_PERMISSION = "android.permission.USE_CREDENTIALS";
+ // A permission that's not granted to this test package.
+ public static final String NOT_GRANTED_PERMISSION = "android.permission.HARDWARE_TEST";
+
+ private static final int BROADCAST_TIMEOUT = 10000;
+ private static final int ROOT_UID = 0;
+
+ private Object mLockObj;
+
+ private ArrayList<BroadcastReceiver> mRegisteredReceiverList;
+
+ private boolean mWallpaperChanged;
+ private BitmapDrawable mOriginalWallpaper;
+ private volatile IBinderPermissionTestService mBinderPermissionTestService;
+ private ServiceConnection mBinderPermissionTestConnection;
+
+ protected Context mContext;
+
+ /**
+ * Returns the Context object that's being tested.
+ */
+ protected Context getContextUnderTest() {
+ return getContext();
+ }
@Override
protected void setUp() throws Exception {
super.setUp();
- mContext = getContext();
+ mContext = getContextUnderTest();
mContext.setTheme(R.style.Test_Theme);
+
+ mLockObj = new Object();
+
+ mRegisteredReceiverList = new ArrayList<BroadcastReceiver>();
+
+ mOriginalWallpaper = (BitmapDrawable) mContext.getWallpaper();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mWallpaperChanged) {
+ mContext.setWallpaper(mOriginalWallpaper.getBitmap());
+ }
+
+ for (BroadcastReceiver receiver : mRegisteredReceiverList) {
+ mContext.unregisterReceiver(receiver);
+ }
+
+ super.tearDown();
}
public void testGetString() {
@@ -354,6 +446,10 @@
private void assertValidFile(File file) throws Exception {
Log.d(TAG, "Checking " + file);
+ if (file.exists()) {
+ assertTrue("File already exists and couldn't be deleted before test: " + file,
+ file.delete());
+ }
assertTrue("Failed to create " + file, file.createNewFile());
assertTrue("Doesn't exist after create " + file, file.exists());
assertTrue("Failed to delete after create " + file, file.delete());
@@ -382,7 +478,7 @@
}
private AttributeSet getAttributeSet(int resourceId) {
- final XmlResourceParser parser = getContext().getResources().getXml(
+ final XmlResourceParser parser = mContext.getResources().getXml(
resourceId);
try {
@@ -397,4 +493,842 @@
assertNotNull(attr);
return attr;
}
+
+ private void registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ mContext.registerReceiver(receiver, filter);
+
+ mRegisteredReceiverList.add(receiver);
+ }
+
+ public void testSendOrderedBroadcast1() throws InterruptedException {
+ final HighPriorityBroadcastReceiver highPriorityReceiver =
+ new HighPriorityBroadcastReceiver();
+ final LowPriorityBroadcastReceiver lowPriorityReceiver =
+ new LowPriorityBroadcastReceiver();
+
+ final IntentFilter filterHighPriority = new IntentFilter(ResultReceiver.MOCK_ACTION);
+ filterHighPriority.setPriority(1);
+ final IntentFilter filterLowPriority = new IntentFilter(ResultReceiver.MOCK_ACTION);
+ registerBroadcastReceiver(highPriorityReceiver, filterHighPriority);
+ registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority);
+
+ final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION);
+ broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendOrderedBroadcast(broadcastIntent, null);
+ new PollingCheck(BROADCAST_TIMEOUT) {
+ @Override
+ protected boolean check() {
+ return highPriorityReceiver.hasReceivedBroadCast()
+ && !lowPriorityReceiver.hasReceivedBroadCast();
+ }
+ }.run();
+
+ synchronized (highPriorityReceiver) {
+ highPriorityReceiver.notify();
+ }
+
+ new PollingCheck(BROADCAST_TIMEOUT) {
+ @Override
+ protected boolean check() {
+ return highPriorityReceiver.hasReceivedBroadCast()
+ && lowPriorityReceiver.hasReceivedBroadCast();
+ }
+ }.run();
+ }
+
+ public void testSendOrderedBroadcast2() throws InterruptedException {
+ final TestBroadcastReceiver broadcastReceiver = new TestBroadcastReceiver();
+ broadcastReceiver.mIsOrderedBroadcasts = true;
+
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_KEPT, VALUE_KEPT);
+ bundle.putString(KEY_REMOVED, VALUE_REMOVED);
+ Intent intent = new Intent(ResultReceiver.MOCK_ACTION);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1,
+ INTIAL_RESULT, bundle);
+
+ synchronized (mLockObj) {
+ try {
+ mLockObj.wait(BROADCAST_TIMEOUT);
+ } catch (InterruptedException e) {
+ fail("unexpected InterruptedException.");
+ }
+ }
+
+ assertTrue("Receiver didn't make any response.", broadcastReceiver.hadReceivedBroadCast());
+ assertEquals("Incorrect code: " + broadcastReceiver.getResultCode(), 3,
+ broadcastReceiver.getResultCode());
+ assertEquals(ACTUAL_RESULT, broadcastReceiver.getResultData());
+ Bundle resultExtras = broadcastReceiver.getResultExtras(false);
+ assertEquals(VALUE_ADDED, resultExtras.getString(KEY_ADDED));
+ assertEquals(VALUE_KEPT, resultExtras.getString(KEY_KEPT));
+ assertNull(resultExtras.getString(KEY_REMOVED));
+ }
+
+ public void testRegisterReceiver1() throws InterruptedException {
+ final FilteredReceiver broadcastReceiver = new FilteredReceiver();
+ final IntentFilter filter = new IntentFilter(MOCK_ACTION1);
+
+ // Test registerReceiver
+ mContext.registerReceiver(broadcastReceiver, filter);
+
+ // Test unwanted intent(action = MOCK_ACTION2)
+ broadcastReceiver.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION2);
+ assertFalse(broadcastReceiver.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver.hadReceivedBroadCast2());
+
+ // Send wanted intent(action = MOCK_ACTION1)
+ broadcastReceiver.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION1);
+ assertTrue(broadcastReceiver.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver.hadReceivedBroadCast2());
+
+ mContext.unregisterReceiver(broadcastReceiver);
+
+ // Test unregisterReceiver
+ FilteredReceiver broadcastReceiver2 = new FilteredReceiver();
+ mContext.registerReceiver(broadcastReceiver2, filter);
+ mContext.unregisterReceiver(broadcastReceiver2);
+
+ // Test unwanted intent(action = MOCK_ACTION2)
+ broadcastReceiver2.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION2);
+ assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
+
+ // Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered.
+ broadcastReceiver2.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION1);
+ assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
+ }
+
+ public void testRegisterReceiver2() throws InterruptedException {
+ FilteredReceiver broadcastReceiver = new FilteredReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(MOCK_ACTION1);
+
+ // Test registerReceiver
+ mContext.registerReceiver(broadcastReceiver, filter, null, null);
+
+ // Test unwanted intent(action = MOCK_ACTION2)
+ broadcastReceiver.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION2);
+ assertFalse(broadcastReceiver.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver.hadReceivedBroadCast2());
+
+ // Send wanted intent(action = MOCK_ACTION1)
+ broadcastReceiver.reset();
+ waitForFilteredIntent(mContext, MOCK_ACTION1);
+ assertTrue(broadcastReceiver.hadReceivedBroadCast1());
+ assertFalse(broadcastReceiver.hadReceivedBroadCast2());
+
+ mContext.unregisterReceiver(broadcastReceiver);
+ }
+
+ public void testAccessWallpaper() throws IOException, InterruptedException {
+ // set Wallpaper by context#setWallpaper(Bitmap)
+ Bitmap bitmap = Bitmap.createBitmap(20, 30, Bitmap.Config.RGB_565);
+ // Test getWallpaper
+ Drawable testDrawable = mContext.getWallpaper();
+ // Test peekWallpaper
+ Drawable testDrawable2 = mContext.peekWallpaper();
+
+ mContext.setWallpaper(bitmap);
+ mWallpaperChanged = true;
+ synchronized(this) {
+ wait(500);
+ }
+
+ assertNotSame(testDrawable, mContext.peekWallpaper());
+ assertNotNull(mContext.getWallpaper());
+ assertNotSame(testDrawable2, mContext.peekWallpaper());
+ assertNotNull(mContext.peekWallpaper());
+
+ // set Wallpaper by context#setWallpaper(InputStream)
+ mContext.clearWallpaper();
+
+ testDrawable = mContext.getWallpaper();
+ InputStream stream = mContext.getResources().openRawResource(R.drawable.scenery);
+
+ mContext.setWallpaper(stream);
+ synchronized (this) {
+ wait(1000);
+ }
+
+ assertNotSame(testDrawable, mContext.peekWallpaper());
+ }
+
+ public void testAccessDatabase() {
+ String DATABASE_NAME = "databasetest";
+ String DATABASE_NAME1 = DATABASE_NAME + "1";
+ String DATABASE_NAME2 = DATABASE_NAME + "2";
+ SQLiteDatabase mDatabase;
+ File mDatabaseFile;
+
+ SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() {
+ public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
+ String editTable, SQLiteQuery query) {
+ return new android.database.sqlite.SQLiteCursor(db, masterQuery, editTable, query) {
+ @Override
+ public boolean requery() {
+ setSelectionArguments(new String[] { "2" });
+ return super.requery();
+ }
+ };
+ }
+ };
+
+ // FIXME: Move cleanup into tearDown()
+ for (String db : mContext.databaseList()) {
+ File f = mContext.getDatabasePath(db);
+ if (f.exists()) {
+ mContext.deleteDatabase(db);
+ }
+ }
+
+ // Test openOrCreateDatabase with null and actual factory
+ mDatabase = mContext.openOrCreateDatabase(DATABASE_NAME1,
+ Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory);
+ assertNotNull(mDatabase);
+ mDatabase.close();
+ mDatabase = mContext.openOrCreateDatabase(DATABASE_NAME2,
+ Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory);
+ assertNotNull(mDatabase);
+ mDatabase.close();
+
+ // Test getDatabasePath
+ File actualDBPath = mContext.getDatabasePath(DATABASE_NAME1);
+
+ // Test databaseList()
+ List<String> list = Arrays.asList(mContext.databaseList());
+ assertEquals(2, list.size());
+ assertTrue("1) database list: " + list, list.contains(DATABASE_NAME1));
+ assertTrue("2) database list: " + list, list.contains(DATABASE_NAME2));
+
+ // Test deleteDatabase()
+ for (int i = 1; i < 3; i++) {
+ mDatabaseFile = mContext.getDatabasePath(DATABASE_NAME + i);
+ assertTrue(mDatabaseFile.exists());
+ mContext.deleteDatabase(DATABASE_NAME + i);
+ mDatabaseFile = new File(actualDBPath, DATABASE_NAME + i);
+ assertFalse(mDatabaseFile.exists());
+ }
+ }
+
+ public void testEnforceUriPermission1() {
+ try {
+ Uri uri = Uri.parse("content://ctstest");
+ mContext.enforceUriPermission(uri, Binder.getCallingPid(),
+ Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ "enforceUriPermission is not working without possessing an IPC.");
+ fail("enforceUriPermission is not working without possessing an IPC.");
+ } catch (SecurityException e) {
+ // If the function is OK, it should throw a SecurityException here because currently no
+ // IPC is handled by this process.
+ }
+ }
+
+ public void testEnforceUriPermission2() {
+ Uri uri = Uri.parse("content://ctstest");
+ try {
+ mContext.enforceUriPermission(uri, NOT_GRANTED_PERMISSION,
+ NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(),
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ "enforceUriPermission is not working without possessing an IPC.");
+ fail("enforceUriPermission is not working without possessing an IPC.");
+ } catch (SecurityException e) {
+ // If the function is ok, it should throw a SecurityException here because currently no
+ // IPC is handled by this process.
+ }
+ }
+
+ public void testGetPackageResourcePath() {
+ assertNotNull(mContext.getPackageResourcePath());
+ }
+
+ public void testStartActivity() {
+ Intent intent = new Intent(mContext, ContextCtsActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ mContext.startActivity(intent);
+ fail("Test startActivity should thow a ActivityNotFoundException here.");
+ } catch (ActivityNotFoundException e) {
+ // Because ContextWrapper is a wrapper class, so no need to test
+ // the details of the function's performance. Getting a result
+ // from the wrapped class is enough for testing.
+ }
+ }
+
+ public void testCreatePackageContext() throws PackageManager.NameNotFoundException {
+ Context actualContext = mContext.createPackageContext(getValidPackageName(),
+ Context.CONTEXT_IGNORE_SECURITY);
+
+ assertNotNull(actualContext);
+ }
+
+ /**
+ * Helper method to retrieve a valid application package name to use for tests.
+ */
+ protected String getValidPackageName() {
+ List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(
+ PackageManager.GET_ACTIVITIES);
+ assertTrue(packages.size() >= 1);
+ return packages.get(0).packageName;
+ }
+
+ public void testGetMainLooper() {
+ assertNotNull(mContext.getMainLooper());
+ }
+
+ public void testGetApplicationContext() {
+ assertSame(mContext.getApplicationContext(), mContext.getApplicationContext());
+ }
+
+ public void testGetSharedPreferences() {
+ SharedPreferences sp;
+ SharedPreferences localSP;
+
+ sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ String packageName = mContext.getPackageName();
+ localSP = mContext.getSharedPreferences(packageName + "_preferences",
+ Context.MODE_PRIVATE);
+ assertSame(sp, localSP);
+ }
+
+ public void testRevokeUriPermission() {
+ Uri uri = Uri.parse("contents://ctstest");
+ mContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ }
+
+ public void testAccessService() throws InterruptedException {
+ MockContextService.reset();
+ bindExpectResult(mContext, new Intent(mContext, MockContextService.class));
+
+ // Check startService
+ assertTrue(MockContextService.hadCalledOnStart());
+ // Check bindService
+ assertTrue(MockContextService.hadCalledOnBind());
+
+ assertTrue(MockContextService.hadCalledOnDestory());
+ // Check unbinService
+ assertTrue(MockContextService.hadCalledOnUnbind());
+ }
+
+ public void testGetPackageCodePath() {
+ assertNotNull(mContext.getPackageCodePath());
+ }
+
+ public void testGetPackageName() {
+ assertEquals("android.content.cts", mContext.getPackageName());
+ }
+
+ public void testGetCacheDir() {
+ assertNotNull(mContext.getCacheDir());
+ }
+
+ public void testGetContentResolver() {
+ assertSame(mContext.getContentResolver(), mContext.getContentResolver());
+ }
+
+ public void testGetFileStreamPath() {
+ String TEST_FILENAME = "TestGetFileStreamPath";
+
+ // Test the path including the input filename
+ String fileStreamPath = mContext.getFileStreamPath(TEST_FILENAME).toString();
+ assertTrue(fileStreamPath.indexOf(TEST_FILENAME) >= 0);
+ }
+
+ public void testGetClassLoader() {
+ assertSame(mContext.getClassLoader(), mContext.getClassLoader());
+ }
+
+ public void testGetWallpaperDesiredMinimumHeightAndWidth() {
+ int height = mContext.getWallpaperDesiredMinimumHeight();
+ int width = mContext.getWallpaperDesiredMinimumWidth();
+
+ // returned value is <= 0, the caller should use the height of the
+ // default display instead.
+ // That is to say, the return values of desired minimumHeight and
+ // minimunWidth are at the same side of 0-dividing line.
+ assertTrue((height > 0 && width > 0) || (height <= 0 && width <= 0));
+ }
+
+ public void testAccessStickyBroadcast() throws InterruptedException {
+ ResultReceiver resultReceiver = new ResultReceiver();
+
+ Intent intent = new Intent(MOCK_STICKY_ACTION);
+ TestBroadcastReceiver stickyReceiver = new TestBroadcastReceiver();
+
+ mContext.sendStickyBroadcast(intent);
+
+ waitForReceiveBroadCast(resultReceiver);
+
+ assertEquals(intent.getAction(), mContext.registerReceiver(stickyReceiver,
+ new IntentFilter(MOCK_STICKY_ACTION)).getAction());
+
+ synchronized (mLockObj) {
+ mLockObj.wait(BROADCAST_TIMEOUT);
+ }
+
+ assertTrue("Receiver didn't make any response.", stickyReceiver.hadReceivedBroadCast());
+
+ mContext.unregisterReceiver(stickyReceiver);
+ mContext.removeStickyBroadcast(intent);
+
+ assertNull(mContext.registerReceiver(stickyReceiver,
+ new IntentFilter(MOCK_STICKY_ACTION)));
+ mContext.unregisterReceiver(stickyReceiver);
+ }
+
+ public void testCheckCallingOrSelfUriPermission() {
+ Uri uri = Uri.parse("content://ctstest");
+
+ int retValue = mContext.checkCallingOrSelfUriPermission(uri,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testGrantUriPermission() {
+ mContext.grantUriPermission("com.android.mms", Uri.parse("contents://ctstest"),
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ }
+
+ public void testCheckPermissionGranted() {
+ int returnValue = mContext.checkPermission(
+ GRANTED_PERMISSION, Process.myPid(), Process.myUid());
+ assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
+ }
+
+ public void testCheckPermissionNotGranted() {
+ int returnValue = mContext.checkPermission(
+ NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid());
+ assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
+ }
+
+ public void testCheckPermissionRootUser() {
+ // Test with root user, everything will be granted.
+ int returnValue = mContext.checkPermission(NOT_GRANTED_PERMISSION, 1, ROOT_UID);
+ assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
+ }
+
+ public void testCheckPermissionInvalidRequest() {
+ // Test with null permission.
+ try {
+ int returnValue = mContext.checkPermission(null, 0, ROOT_UID);
+ fail("checkPermission should not accept null permission");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // Test with invalid uid and included granted permission.
+ int returnValue = mContext.checkPermission(GRANTED_PERMISSION, 1, -11);
+ assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
+ }
+
+ public void testCheckSelfPermissionGranted() {
+ int returnValue = mContext.checkSelfPermission(GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
+ }
+
+ public void testCheckSelfPermissionNotGranted() {
+ int returnValue = mContext.checkSelfPermission(NOT_GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
+ }
+
+ public void testEnforcePermissionGranted() {
+ mContext.enforcePermission(
+ GRANTED_PERMISSION, Process.myPid(), Process.myUid(),
+ "permission isn't granted");
+ }
+
+ public void testEnforcePermissionNotGranted() {
+ try {
+ mContext.enforcePermission(
+ NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid(),
+ "permission isn't granted");
+ fail("Permission shouldn't be granted.");
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testCheckCallingOrSelfPermission_noIpc() {
+ // There's no ongoing Binder call, so this package's permissions are checked.
+ int retValue = mContext.checkCallingOrSelfPermission(GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
+
+ retValue = mContext.checkCallingOrSelfPermission(NOT_GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testCheckCallingOrSelfPermission_ipc() throws Exception {
+ bindBinderPermissionTestService();
+ try {
+ int retValue = mBinderPermissionTestService.doCheckCallingOrSelfPermission(
+ GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
+
+ retValue = mBinderPermissionTestService.doCheckCallingOrSelfPermission(
+ NOT_GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ } finally {
+ mContext.unbindService(mBinderPermissionTestConnection);
+ }
+ }
+
+ public void testEnforceCallingOrSelfPermission_noIpc() {
+ // There's no ongoing Binder call, so this package's permissions are checked.
+ mContext.enforceCallingOrSelfPermission(
+ GRANTED_PERMISSION, "permission isn't granted");
+
+ try {
+ mContext.enforceCallingOrSelfPermission(
+ NOT_GRANTED_PERMISSION, "permission isn't granted");
+ fail("Permission shouldn't be granted.");
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testEnforceCallingOrSelfPermission_ipc() throws Exception {
+ bindBinderPermissionTestService();
+ try {
+ mBinderPermissionTestService.doEnforceCallingOrSelfPermission(GRANTED_PERMISSION);
+
+ try {
+ mBinderPermissionTestService.doEnforceCallingOrSelfPermission(
+ NOT_GRANTED_PERMISSION);
+ fail("Permission shouldn't be granted.");
+ } catch (SecurityException expected) {
+ }
+ } finally {
+ mContext.unbindService(mBinderPermissionTestConnection);
+ }
+ }
+
+ public void testCheckCallingPermission_noIpc() {
+ // Denied because no IPC is active.
+ int retValue = mContext.checkCallingPermission(GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testEnforceCallingPermission_noIpc() {
+ try {
+ mContext.enforceCallingPermission(
+ GRANTED_PERMISSION,
+ "enforceCallingPermission is not working without possessing an IPC.");
+ fail("enforceCallingPermission is not working without possessing an IPC.");
+ } catch (SecurityException e) {
+ // Currently no IPC is handled by this process, this exception is expected
+ }
+ }
+
+ public void testEnforceCallingPermission_ipc() throws Exception {
+ bindBinderPermissionTestService();
+ try {
+ mBinderPermissionTestService.doEnforceCallingPermission(GRANTED_PERMISSION);
+
+ try {
+ mBinderPermissionTestService.doEnforceCallingPermission(NOT_GRANTED_PERMISSION);
+ fail("Permission shouldn't be granted.");
+ } catch (SecurityException expected) {
+ }
+ } finally {
+ mContext.unbindService(mBinderPermissionTestConnection);
+ }
+ }
+
+ public void testCheckCallingPermission_ipc() throws Exception {
+ bindBinderPermissionTestService();
+ try {
+ int returnValue = mBinderPermissionTestService.doCheckCallingPermission(
+ GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
+
+ returnValue = mBinderPermissionTestService.doCheckCallingPermission(
+ NOT_GRANTED_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
+ } finally {
+ mContext.unbindService(mBinderPermissionTestConnection);
+ }
+ }
+
+ private void bindBinderPermissionTestService() {
+ Intent intent = new Intent(mContext, IBinderPermissionTestService.class);
+ intent.setComponent(new ComponentName(
+ "com.android.cts", "com.android.cts.BinderPermissionTestService"));
+
+ mBinderPermissionTestConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ mBinderPermissionTestService =
+ IBinderPermissionTestService.Stub.asInterface(iBinder);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ }
+ };
+
+ assertTrue("Service not bound", mContext.bindService(
+ intent, mBinderPermissionTestConnection, Context.BIND_AUTO_CREATE));
+
+ new PollingCheck(15 * 1000) {
+ protected boolean check() {
+ return mBinderPermissionTestService != null; // Service was bound.
+ }
+ }.run();
+ }
+
+ public void testCheckUriPermission1() {
+ Uri uri = Uri.parse("content://ctstest");
+
+ int retValue = mContext.checkUriPermission(uri, Binder.getCallingPid(), 0,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
+
+ retValue = mContext.checkUriPermission(uri, Binder.getCallingPid(),
+ Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testCheckUriPermission2() {
+ Uri uri = Uri.parse("content://ctstest");
+
+ int retValue = mContext.checkUriPermission(uri, NOT_GRANTED_PERMISSION,
+ NOT_GRANTED_PERMISSION, Binder.getCallingPid(), 0,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
+
+ retValue = mContext.checkUriPermission(uri, NOT_GRANTED_PERMISSION,
+ NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(),
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testCheckCallingUriPermission() {
+ Uri uri = Uri.parse("content://ctstest");
+
+ int retValue = mContext.checkCallingUriPermission(uri,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertEquals(PackageManager.PERMISSION_DENIED, retValue);
+ }
+
+ public void testEnforceCallingUriPermission() {
+ try {
+ Uri uri = Uri.parse("content://ctstest");
+ mContext.enforceCallingUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ "enforceCallingUriPermission is not working without possessing an IPC.");
+ fail("enforceCallingUriPermission is not working without possessing an IPC.");
+ } catch (SecurityException e) {
+ // If the function is OK, it should throw a SecurityException here because currently no
+ // IPC is handled by this process.
+ }
+ }
+
+ public void testGetDir() {
+ File dir = mContext.getDir("testpath", Context.MODE_PRIVATE);
+ assertNotNull(dir);
+ dir.delete();
+ }
+
+ public void testGetPackageManager() {
+ assertSame(mContext.getPackageManager(), mContext.getPackageManager());
+ }
+
+ public void testSendBroadcast1() throws InterruptedException {
+ final ResultReceiver receiver = new ResultReceiver();
+
+ registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
+
+ mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION));
+
+ new PollingCheck(BROADCAST_TIMEOUT){
+ @Override
+ protected boolean check() {
+ return receiver.hasReceivedBroadCast();
+ }
+ }.run();
+ }
+
+ public void testSendBroadcast2() throws InterruptedException {
+ final ResultReceiver receiver = new ResultReceiver();
+
+ registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
+
+ mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION), null);
+
+ new PollingCheck(BROADCAST_TIMEOUT){
+ @Override
+ protected boolean check() {
+ return receiver.hasReceivedBroadCast();
+ }
+ }.run();
+ }
+
+ public void testEnforceCallingOrSelfUriPermission() {
+ try {
+ Uri uri = Uri.parse("content://ctstest");
+ mContext.enforceCallingOrSelfUriPermission(uri,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ "enforceCallingOrSelfUriPermission is not working without possessing an IPC.");
+ fail("enforceCallingOrSelfUriPermission is not working without possessing an IPC.");
+ } catch (SecurityException e) {
+ // If the function is OK, it should throw a SecurityException here because currently no
+ // IPC is handled by this process.
+ }
+ }
+
+ public void testGetAssets() {
+ assertSame(mContext.getAssets(), mContext.getAssets());
+ }
+
+ public void testGetResources() {
+ assertSame(mContext.getResources(), mContext.getResources());
+ }
+
+ public void testStartInstrumentation() {
+ // Use wrong name
+ ComponentName cn = new ComponentName("com.android",
+ "com.android.content.FalseLocalSampleInstrumentation");
+ assertNotNull(cn);
+ assertNotNull(mContext);
+ // If the target instrumentation is wrong, the function should return false.
+ assertFalse(mContext.startInstrumentation(cn, null, null));
+ }
+
+ private void bindExpectResult(Context context, Intent service)
+ throws InterruptedException {
+ if (service == null) {
+ fail("No service created!");
+ }
+ TestConnection conn = new TestConnection(true, false);
+
+ context.bindService(service, conn, Context.BIND_AUTO_CREATE);
+ context.startService(service);
+
+ // Wait for a short time, so the service related operations could be
+ // working.
+ synchronized (this) {
+ wait(2500);
+ }
+ // Test stop Service
+ assertTrue(context.stopService(service));
+ context.unbindService(conn);
+
+ synchronized (this) {
+ wait(1000);
+ }
+ }
+
+ private interface Condition {
+ public boolean onCondition();
+ }
+
+ private synchronized void waitForCondition(Condition con) throws InterruptedException {
+ // check the condition every 1 second until the condition is fulfilled
+ // and wait for 3 seconds at most
+ for (int i = 0; !con.onCondition() && i <= 3; i++) {
+ wait(1000);
+ }
+ }
+
+ private void waitForReceiveBroadCast(final ResultReceiver receiver)
+ throws InterruptedException {
+ Condition con = new Condition() {
+ public boolean onCondition() {
+ return receiver.hasReceivedBroadCast();
+ }
+ };
+ waitForCondition(con);
+ }
+
+ private void waitForFilteredIntent(Context context, final String action)
+ throws InterruptedException {
+ context.sendBroadcast(new Intent(action), null);
+
+ synchronized (mLockObj) {
+ mLockObj.wait(BROADCAST_TIMEOUT);
+ }
+ }
+
+ private final class TestBroadcastReceiver extends BroadcastReceiver {
+ boolean mHadReceivedBroadCast;
+ boolean mIsOrderedBroadcasts;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (this) {
+ if (mIsOrderedBroadcasts) {
+ setResultCode(3);
+ setResultData(ACTUAL_RESULT);
+ }
+
+ Bundle map = getResultExtras(false);
+ if (map != null) {
+ map.remove(KEY_REMOVED);
+ map.putString(KEY_ADDED, VALUE_ADDED);
+ }
+ mHadReceivedBroadCast = true;
+ this.notifyAll();
+ }
+
+ synchronized (mLockObj) {
+ mLockObj.notify();
+ }
+ }
+
+ boolean hadReceivedBroadCast() {
+ return mHadReceivedBroadCast;
+ }
+
+ void reset(){
+ mHadReceivedBroadCast = false;
+ }
+ }
+
+ private class FilteredReceiver extends BroadcastReceiver {
+ private boolean mHadReceivedBroadCast1 = false;
+ private boolean mHadReceivedBroadCast2 = false;
+
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (MOCK_ACTION1.equals(action)) {
+ mHadReceivedBroadCast1 = true;
+ } else if (MOCK_ACTION2.equals(action)) {
+ mHadReceivedBroadCast2 = true;
+ }
+
+ synchronized (mLockObj) {
+ mLockObj.notify();
+ }
+ }
+
+ public boolean hadReceivedBroadCast1() {
+ return mHadReceivedBroadCast1;
+ }
+
+ public boolean hadReceivedBroadCast2() {
+ return mHadReceivedBroadCast2;
+ }
+
+ public void reset(){
+ mHadReceivedBroadCast1 = false;
+ mHadReceivedBroadCast2 = false;
+ }
+ }
+
+ private class TestConnection implements ServiceConnection {
+ public TestConnection(boolean expectDisconnect, boolean setReporter) {
+ }
+
+ void setMonitor(boolean v) {
+ }
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ }
}
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index 408855d..abf3506 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -16,117 +16,29 @@
package android.content.cts;
-import android.content.cts.R;
-
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteCursorDriver;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteQuery;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Process;
-import android.preference.PreferenceManager;
-import android.test.AndroidTestCase;
-import android.view.WindowManager;
-
-import com.android.compatibility.common.util.PollingCheck;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
/**
* Test {@link ContextWrapper}.
+ *
+ * <p>
+ * This class inherits most of its test methods from its parent ContextTest.
+ * Since ContextWrapper delegates its requests to the Context, the same test cases should pass
+ * for both Context and ContextWrapper.
+ *
+ * <p>
+ * There are some tests for ContextWrapper that don't make sense for Context - those are included
+ * in this class.
*/
-public class ContextWrapperTest extends AndroidTestCase {
- private static final String ACTUAL_RESULT = "ResultSetByReceiver";
+public class ContextWrapperTest extends ContextTest {
- private static final String INTIAL_RESULT = "IntialResult";
-
- private static final String VALUE_ADDED = "ValueAdded";
- private static final String KEY_ADDED = "AddedByReceiver";
-
- private static final String VALUE_REMOVED = "ValueWillBeRemove";
- private static final String KEY_REMOVED = "ToBeRemoved";
-
- private static final String VALUE_KEPT = "ValueKept";
- private static final String KEY_KEPT = "ToBeKept";
-
- private static final String MOCK_STICKY_ACTION = "android.content.cts.ContextWrapperTest."
- + "STICKY_BROADCAST_RESULT";
-
- private static final String ACTION_BROADCAST_TESTORDER =
- "android.content.cts.ContextWrapperTest.BROADCAST_TESTORDER";
- private final static String MOCK_ACTION1 = ACTION_BROADCAST_TESTORDER + "1";
- private final static String MOCK_ACTION2 = ACTION_BROADCAST_TESTORDER + "2";
-
- // A permission that's granted to this test package.
- public static final String GRANTED_PERMISSION = "android.permission.USE_CREDENTIALS";
- // A permission that's not granted to this test package.
- public static final String NOT_GRANTED_PERMISSION = "android.permission.HARDWARE_TEST";
-
- private static final int BROADCAST_TIMEOUT = 10000;
- private static final int ROOT_UID = 0;
-
- private Context mContext;
-
- private ContextWrapper mContextWrapper;
- private Object mLockObj;
-
- private ArrayList<BroadcastReceiver> mRegisteredReceiverList;
-
- private boolean mWallpaperChanged;
- private BitmapDrawable mOriginalWallpaper;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mLockObj = new Object();
- mContext = getContext();
- mContextWrapper = new ContextWrapper(mContext);
-
- mRegisteredReceiverList = new ArrayList<BroadcastReceiver>();
-
- mOriginalWallpaper = (BitmapDrawable) mContextWrapper.getWallpaper();
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (mWallpaperChanged) {
- mContextWrapper.setWallpaper(mOriginalWallpaper.getBitmap());
- }
-
- for (BroadcastReceiver receiver : mRegisteredReceiverList) {
- mContextWrapper.unregisterReceiver(receiver);
- }
-
- super.tearDown();
- }
-
- private void registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter) {
- mContextWrapper.registerReceiver(receiver, filter);
-
- mRegisteredReceiverList.add(receiver);
+ /**
+ * Returns the ContextWrapper object that's being tested.
+ */
+ protected Context getContextUnderTest() {
+ return new ContextWrapper(getContext());
}
public void testConstructor() {
@@ -136,344 +48,12 @@
new ContextWrapper(null);
}
- public void testSendOrderedBroadcast1() throws InterruptedException {
- final HighPriorityBroadcastReceiver highPriorityReceiver =
- new HighPriorityBroadcastReceiver();
- final LowPriorityBroadcastReceiver lowPriorityReceiver =
- new LowPriorityBroadcastReceiver();
-
- final IntentFilter filterHighPriority = new IntentFilter(ResultReceiver.MOCK_ACTION);
- filterHighPriority.setPriority(1);
- final IntentFilter filterLowPriority = new IntentFilter(ResultReceiver.MOCK_ACTION);
- registerBroadcastReceiver(highPriorityReceiver, filterHighPriority);
- registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority);
-
- final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION);
- broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContextWrapper.sendOrderedBroadcast(broadcastIntent, null);
- new PollingCheck(BROADCAST_TIMEOUT) {
- @Override
- protected boolean check() {
- return highPriorityReceiver.hasReceivedBroadCast()
- && !lowPriorityReceiver.hasReceivedBroadCast();
- }
- }.run();
-
- synchronized (highPriorityReceiver) {
- highPriorityReceiver.notify();
- }
-
- new PollingCheck(BROADCAST_TIMEOUT) {
- @Override
- protected boolean check() {
- return highPriorityReceiver.hasReceivedBroadCast()
- && lowPriorityReceiver.hasReceivedBroadCast();
- }
- }.run();
- }
-
- public void testSendOrderedBroadcast2() throws InterruptedException {
- final TestBroadcastReceiver broadcastReceiver = new TestBroadcastReceiver();
- broadcastReceiver.mIsOrderedBroadcasts = true;
-
- Bundle bundle = new Bundle();
- bundle.putString(KEY_KEPT, VALUE_KEPT);
- bundle.putString(KEY_REMOVED, VALUE_REMOVED);
- Intent intent = new Intent(ResultReceiver.MOCK_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContextWrapper.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1,
- INTIAL_RESULT, bundle);
-
- synchronized (mLockObj) {
- try {
- mLockObj.wait(BROADCAST_TIMEOUT);
- } catch (InterruptedException e) {
- fail("unexpected InterruptedException.");
- }
- }
-
- assertTrue("Receiver didn't make any response.", broadcastReceiver.hadReceivedBroadCast());
- assertEquals("Incorrect code: " + broadcastReceiver.getResultCode(), 3,
- broadcastReceiver.getResultCode());
- assertEquals(ACTUAL_RESULT, broadcastReceiver.getResultData());
- Bundle resultExtras = broadcastReceiver.getResultExtras(false);
- assertEquals(VALUE_ADDED, resultExtras.getString(KEY_ADDED));
- assertEquals(VALUE_KEPT, resultExtras.getString(KEY_KEPT));
- assertNull(resultExtras.getString(KEY_REMOVED));
- }
-
- public void testRegisterReceiver1() throws InterruptedException {
- final FilteredReceiver broadcastReceiver = new FilteredReceiver();
- final IntentFilter filter = new IntentFilter(MOCK_ACTION1);
-
- // Test registerReceiver
- mContextWrapper.registerReceiver(broadcastReceiver, filter);
-
- // Test unwanted intent(action = MOCK_ACTION2)
- broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
- assertFalse(broadcastReceiver.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver.hadReceivedBroadCast2());
-
- // Send wanted intent(action = MOCK_ACTION1)
- broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
- assertTrue(broadcastReceiver.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver.hadReceivedBroadCast2());
-
- mContextWrapper.unregisterReceiver(broadcastReceiver);
-
- // Test unregisterReceiver
- FilteredReceiver broadcastReceiver2 = new FilteredReceiver();
- mContextWrapper.registerReceiver(broadcastReceiver2, filter);
- mContextWrapper.unregisterReceiver(broadcastReceiver2);
-
- // Test unwanted intent(action = MOCK_ACTION2)
- broadcastReceiver2.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
- assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
-
- // Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered.
- broadcastReceiver2.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
- assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
- }
-
- public void testRegisterReceiver2() throws InterruptedException {
- FilteredReceiver broadcastReceiver = new FilteredReceiver();
- IntentFilter filter = new IntentFilter();
- filter.addAction(MOCK_ACTION1);
-
- // Test registerReceiver
- mContextWrapper.registerReceiver(broadcastReceiver, filter, null, null);
-
- // Test unwanted intent(action = MOCK_ACTION2)
- broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
- assertFalse(broadcastReceiver.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver.hadReceivedBroadCast2());
-
- // Send wanted intent(action = MOCK_ACTION1)
- broadcastReceiver.reset();
- waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
- assertTrue(broadcastReceiver.hadReceivedBroadCast1());
- assertFalse(broadcastReceiver.hadReceivedBroadCast2());
-
- mContextWrapper.unregisterReceiver(broadcastReceiver);
- }
-
- public void testAccessWallpaper() throws IOException, InterruptedException {
- // set Wallpaper by contextWrapper#setWallpaper(Bitmap)
- Bitmap bitmap = Bitmap.createBitmap(20, 30, Bitmap.Config.RGB_565);
- // Test getWallpaper
- Drawable testDrawable = mContextWrapper.getWallpaper();
- // Test peekWallpaper
- Drawable testDrawable2 = mContextWrapper.peekWallpaper();
-
- mContextWrapper.setWallpaper(bitmap);
- mWallpaperChanged = true;
- synchronized(this) {
- wait(500);
- }
-
- assertNotSame(testDrawable, mContextWrapper.peekWallpaper());
- assertNotNull(mContextWrapper.getWallpaper());
- assertNotSame(testDrawable2, mContextWrapper.peekWallpaper());
- assertNotNull(mContextWrapper.peekWallpaper());
-
- // set Wallpaper by contextWrapper#setWallpaper(InputStream)
- mContextWrapper.clearWallpaper();
-
- testDrawable = mContextWrapper.getWallpaper();
- InputStream stream = mContextWrapper.getResources().openRawResource(R.drawable.scenery);
-
- mContextWrapper.setWallpaper(stream);
- synchronized (this) {
- wait(1000);
- }
-
- assertNotSame(testDrawable, mContextWrapper.peekWallpaper());
- }
-
- public void testAccessDatabase() {
- String DATABASE_NAME = "databasetest";
- String DATABASE_NAME1 = DATABASE_NAME + "1";
- String DATABASE_NAME2 = DATABASE_NAME + "2";
- SQLiteDatabase mDatabase;
- File mDatabaseFile;
-
- SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() {
- public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
- String editTable, SQLiteQuery query) {
- return new android.database.sqlite.SQLiteCursor(db, masterQuery, editTable, query) {
- @Override
- public boolean requery() {
- setSelectionArguments(new String[] { "2" });
- return super.requery();
- }
- };
- }
- };
-
- // FIXME: Move cleanup into tearDown()
- for (String db : mContextWrapper.databaseList()) {
- File f = mContextWrapper.getDatabasePath(db);
- if (f.exists()) {
- mContextWrapper.deleteDatabase(db);
- }
- }
-
- // Test openOrCreateDatabase with null and actual factory
- mDatabase = mContextWrapper.openOrCreateDatabase(DATABASE_NAME1,
- ContextWrapper.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory);
- assertNotNull(mDatabase);
- mDatabase.close();
- mDatabase = mContextWrapper.openOrCreateDatabase(DATABASE_NAME2,
- ContextWrapper.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory);
- assertNotNull(mDatabase);
- mDatabase.close();
-
- // Test getDatabasePath
- File actualDBPath = mContextWrapper.getDatabasePath(DATABASE_NAME1);
-
- // Test databaseList()
- List<String> list = Arrays.asList(mContextWrapper.databaseList());
- assertEquals(2, list.size());
- assertTrue("1) database list: " + list, list.contains(DATABASE_NAME1));
- assertTrue("2) database list: " + list, list.contains(DATABASE_NAME2));
-
- // Test deleteDatabase()
- for (int i = 1; i < 3; i++) {
- mDatabaseFile = mContextWrapper.getDatabasePath(DATABASE_NAME + i);
- assertTrue(mDatabaseFile.exists());
- mContextWrapper.deleteDatabase(DATABASE_NAME + i);
- mDatabaseFile = new File(actualDBPath, DATABASE_NAME + i);
- assertFalse(mDatabaseFile.exists());
- }
- }
-
- public void testEnforceUriPermission1() {
- try {
- Uri uri = Uri.parse("content://ctstest");
- mContextWrapper.enforceUriPermission(uri, Binder.getCallingPid(),
- Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- "enforceUriPermission is not working without possessing an IPC.");
- fail("enforceUriPermission is not working without possessing an IPC.");
- } catch (SecurityException e) {
- // If the function is OK, it should throw a SecurityException here because currently no
- // IPC is handled by this process.
- }
- }
-
- public void testEnforceUriPermission2() {
- Uri uri = Uri.parse("content://ctstest");
- try {
- mContextWrapper.enforceUriPermission(uri, NOT_GRANTED_PERMISSION,
- NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(),
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- "enforceUriPermission is not working without possessing an IPC.");
- fail("enforceUriPermission is not working without possessing an IPC.");
- } catch (SecurityException e) {
- // If the function is ok, it should throw a SecurityException here because currently no
- // IPC is handled by this process.
- }
- }
-
- public void testGetPackageResourcePath() {
- assertNotNull(mContextWrapper.getPackageResourcePath());
- }
-
- public void testStartActivity() {
- Intent intent = new Intent(mContext, ContextWrapperCtsActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mContextWrapper.startActivity(intent);
- fail("Test startActivity should thow a ActivityNotFoundException here.");
- } catch (ActivityNotFoundException e) {
- // Because ContextWrapper is a wrapper class, so no need to test
- // the details of the function's performance. Getting a result
- // from the wrapped class is enough for testing.
- }
- }
-
- public void testCreatePackageContext() throws PackageManager.NameNotFoundException {
- Context actualContext = mContextWrapper.createPackageContext(getValidPackageName(),
- Context.CONTEXT_IGNORE_SECURITY);
-
- assertNotNull(actualContext);
- }
-
- /**
- * Helper method to retrieve a valid application package name to use for tests.
- */
- private String getValidPackageName() {
- List<PackageInfo> packages = mContextWrapper.getPackageManager().getInstalledPackages(
- PackageManager.GET_ACTIVITIES);
- assertTrue(packages.size() >= 1);
- return packages.get(0).packageName;
- }
-
- public void testGetMainLooper() {
- assertNotNull(mContextWrapper.getMainLooper());
- }
-
- public void testGetApplicationContext() {
- assertSame(mContext.getApplicationContext(), mContextWrapper.getApplicationContext());
- }
-
- public void testGetSharedPreferences() {
- SharedPreferences sp;
- SharedPreferences localSP;
-
- sp = PreferenceManager.getDefaultSharedPreferences(mContext);
- String packageName = mContextWrapper.getPackageName();
- localSP = mContextWrapper.getSharedPreferences(packageName + "_preferences",
- Context.MODE_PRIVATE);
- assertSame(sp, localSP);
- }
-
- public void testRevokeUriPermission() {
- Uri uri = Uri.parse("contents://ctstest");
- mContextWrapper.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- }
-
- public void testAccessService() throws InterruptedException {
- MockContextWrapperService.reset();
- bindExpectResult(mContextWrapper, new Intent(mContext, MockContextWrapperService.class));
-
- // Check startService
- assertTrue(MockContextWrapperService.hadCalledOnStart());
- // Check bindService
- assertTrue(MockContextWrapperService.hadCalledOnBind());
-
- assertTrue(MockContextWrapperService.hadCalledOnDestory());
- // Check unbinService
- assertTrue(MockContextWrapperService.hadCalledOnUnbind());
- }
-
- public void testGetPackageCodePath() {
- assertNotNull(mContextWrapper.getPackageCodePath());
- }
-
- public void testGetPackageName() {
- assertEquals("android.content.cts", mContextWrapper.getPackageName());
- }
-
- public void testGetCacheDir() {
- assertNotNull(mContextWrapper.getCacheDir());
- }
-
- public void testGetContentResolver() {
- assertSame(mContext.getContentResolver(), mContextWrapper.getContentResolver());
- }
-
public void testAccessBaseContext() throws PackageManager.NameNotFoundException {
- MockContextWrapper testContextWrapper = new MockContextWrapper(mContext);
+ Context context = getContext();
+ MockContextWrapper testContextWrapper = new MockContextWrapper(context);
// Test getBaseContext()
- assertSame(mContext, testContextWrapper.getBaseContext());
+ assertSame(context, testContextWrapper.getBaseContext());
Context secondContext = testContextWrapper.createPackageContext(getValidPackageName(),
Context.CONTEXT_IGNORE_SECURITY);
@@ -487,352 +67,7 @@
}
}
- public void testGetFileStreamPath() {
- String TEST_FILENAME = "TestGetFileStreamPath";
-
- // Test the path including the input filename
- String fileStreamPath = mContextWrapper.getFileStreamPath(TEST_FILENAME).toString();
- assertTrue(fileStreamPath.indexOf(TEST_FILENAME) >= 0);
- }
-
- public void testGetClassLoader() {
- assertSame(mContext.getClassLoader(), mContextWrapper.getClassLoader());
- }
-
- public void testGetWallpaperDesiredMinimumHeightAndWidth() {
- int height = mContextWrapper.getWallpaperDesiredMinimumHeight();
- int width = mContextWrapper.getWallpaperDesiredMinimumWidth();
-
- // returned value is <= 0, the caller should use the height of the
- // default display instead.
- // That is to say, the return values of desired minimumHeight and
- // minimunWidth are at the same side of 0-dividing line.
- assertTrue((height > 0 && width > 0) || (height <= 0 && width <= 0));
- }
-
- public void testAccessStickyBroadcast() throws InterruptedException {
- ResultReceiver resultReceiver = new ResultReceiver();
-
- Intent intent = new Intent(MOCK_STICKY_ACTION);
- TestBroadcastReceiver stickyReceiver = new TestBroadcastReceiver();
-
- mContextWrapper.sendStickyBroadcast(intent);
-
- waitForReceiveBroadCast(resultReceiver);
-
- assertEquals(intent.getAction(), mContextWrapper.registerReceiver(stickyReceiver,
- new IntentFilter(MOCK_STICKY_ACTION)).getAction());
-
- synchronized (mLockObj) {
- mLockObj.wait(BROADCAST_TIMEOUT);
- }
-
- assertTrue("Receiver didn't make any response.", stickyReceiver.hadReceivedBroadCast());
-
- mContextWrapper.unregisterReceiver(stickyReceiver);
- mContextWrapper.removeStickyBroadcast(intent);
-
- assertNull(mContextWrapper.registerReceiver(stickyReceiver,
- new IntentFilter(MOCK_STICKY_ACTION)));
- mContextWrapper.unregisterReceiver(stickyReceiver);
- }
-
- public void testCheckCallingOrSelfUriPermission() {
- Uri uri = Uri.parse("content://ctstest");
-
- int retValue = mContextWrapper.checkCallingOrSelfUriPermission(uri,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, retValue);
- }
-
- public void testGrantUriPermission() {
- mContextWrapper.grantUriPermission("com.android.mms", Uri.parse("contents://ctstest"),
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- }
-
- public void testCheckPermissionGranted() {
- int returnValue = mContextWrapper.checkPermission(
- GRANTED_PERMISSION, Process.myPid(), Process.myUid());
- assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
- }
-
- public void testCheckPermissionNotGranted() {
- int returnValue = mContextWrapper.checkPermission(
- NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid());
- assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
- }
-
- public void testCheckPermissionRootUser() {
- // Test with root user, everything will be granted.
- int returnValue = mContextWrapper.checkPermission(NOT_GRANTED_PERMISSION, 1, ROOT_UID);
- assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
- }
-
- public void testCheckPermissionInvalidRequest() {
- // Test with null permission.
- try {
- int returnValue = mContextWrapper.checkPermission(null, 0, ROOT_UID);
- fail("checkPermission should not accept null permission");
- } catch (IllegalArgumentException e) {
- }
-
- // Test with invalid uid and included granted permission.
- int returnValue = mContextWrapper.checkPermission(GRANTED_PERMISSION, 1, -11);
- assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
- }
-
- public void testCheckSelfPermissionGranted() {
- int returnValue = mContextWrapper.checkSelfPermission(GRANTED_PERMISSION);
- assertEquals(PackageManager.PERMISSION_GRANTED, returnValue);
- }
-
- public void testCheckSelfPermissionNotGranted() {
- int returnValue = mContextWrapper.checkSelfPermission(NOT_GRANTED_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, returnValue);
- }
-
- public void testEnforcePermissionGranted() {
- mContextWrapper.enforcePermission(
- GRANTED_PERMISSION, Process.myPid(), Process.myUid(),
- "permission isn't granted");
- }
-
- public void testEnforcePermissionNotGranted() {
- try {
- mContextWrapper.enforcePermission(
- NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid(),
- "permission isn't granted");
- fail("Permission shouldn't be granted.");
- } catch (SecurityException expected) {
- }
- }
-
- public void testCheckCallingOrSelfPermissionGranted() {
- int retValue = mContextWrapper.checkCallingOrSelfPermission(GRANTED_PERMISSION);
- assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
- }
-
- public void testEnforceCallingOrSelfPermissionGranted() {
- mContextWrapper.enforceCallingOrSelfPermission(
- GRANTED_PERMISSION, "permission isn't granted");
- }
-
- public void testEnforceCallingOrSelfPermissionNotGranted() {
- try {
- mContextWrapper.enforceCallingOrSelfPermission(
- NOT_GRANTED_PERMISSION, "permission isn't granted");
- fail("Permission shouldn't be granted.");
- } catch (SecurityException expected) {
- }
- }
-
- public void testCheckCallingPermission() {
- // Denied because no IPC is active.
- int retValue = mContextWrapper.checkCallingPermission(GRANTED_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, retValue);
- }
-
- public void testEnforceCallingPermission() {
- try {
- mContextWrapper.enforceCallingPermission(
- GRANTED_PERMISSION,
- "enforceCallingPermission is not working without possessing an IPC.");
- fail("enforceCallingPermission is not working without possessing an IPC.");
- } catch (SecurityException e) {
- // Currently no IPC is handled by this process, this exception is expected
- }
- }
-
- public void testCheckUriPermission1() {
- Uri uri = Uri.parse("content://ctstest");
-
- int retValue = mContextWrapper.checkUriPermission(uri, Binder.getCallingPid(), 0,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
-
- retValue = mContextWrapper.checkUriPermission(uri, Binder.getCallingPid(),
- Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, retValue);
- }
-
- public void testCheckUriPermission2() {
- Uri uri = Uri.parse("content://ctstest");
-
- int retValue = mContextWrapper.checkUriPermission(uri, NOT_GRANTED_PERMISSION,
- NOT_GRANTED_PERMISSION, Binder.getCallingPid(), 0,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_GRANTED, retValue);
-
- retValue = mContextWrapper.checkUriPermission(uri, NOT_GRANTED_PERMISSION,
- NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(),
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, retValue);
- }
-
- public void testCheckCallingUriPermission() {
- Uri uri = Uri.parse("content://ctstest");
-
- int retValue = mContextWrapper.checkCallingUriPermission(uri,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- assertEquals(PackageManager.PERMISSION_DENIED, retValue);
- }
-
- public void testEnforceCallingUriPermission() {
- try {
- Uri uri = Uri.parse("content://ctstest");
- mContextWrapper.enforceCallingUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- "enforceCallingUriPermission is not working without possessing an IPC.");
- fail("enforceCallingUriPermission is not working without possessing an IPC.");
- } catch (SecurityException e) {
- // If the function is OK, it should throw a SecurityException here because currently no
- // IPC is handled by this process.
- }
- }
-
- public void testGetDir() {
- File dir = mContextWrapper.getDir("testpath", Context.MODE_PRIVATE);
- assertNotNull(dir);
- dir.delete();
- }
-
- public void testGetPackageManager() {
- assertSame(mContext.getPackageManager(), mContextWrapper.getPackageManager());
- }
-
- public void testSendBroadcast1() throws InterruptedException {
- final ResultReceiver receiver = new ResultReceiver();
-
- registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
-
- mContextWrapper.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION));
-
- new PollingCheck(BROADCAST_TIMEOUT){
- @Override
- protected boolean check() {
- return receiver.hasReceivedBroadCast();
- }
- }.run();
- }
-
- public void testSendBroadcast2() throws InterruptedException {
- final ResultReceiver receiver = new ResultReceiver();
-
- registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION));
-
- mContextWrapper.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION), null);
-
- new PollingCheck(BROADCAST_TIMEOUT){
- @Override
- protected boolean check() {
- return receiver.hasReceivedBroadCast();
- }
- }.run();
- }
-
- public void testEnforceCallingOrSelfUriPermission() {
- try {
- Uri uri = Uri.parse("content://ctstest");
- mContextWrapper.enforceCallingOrSelfUriPermission(uri,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- "enforceCallingOrSelfUriPermission is not working without possessing an IPC.");
- fail("enforceCallingOrSelfUriPermission is not working without possessing an IPC.");
- } catch (SecurityException e) {
- // If the function is OK, it should throw a SecurityException here because currently no
- // IPC is handled by this process.
- }
- }
-
- public void testGetSystemService() {
- // Test invalid service name
- assertNull(mContextWrapper.getSystemService("invalid"));
-
- // Test valid service name
- assertNotNull(mContextWrapper.getSystemService(Context.WINDOW_SERVICE));
- }
-
- public void testGetSystemServiceByClass() {
- // Test invalid service class
- assertNull(mContextWrapper.getSystemService(Object.class));
-
- // Test valid service name
- assertNotNull(mContextWrapper.getSystemService(WindowManager.class));
- assertEquals(mContextWrapper.getSystemService(Context.WINDOW_SERVICE),
- mContextWrapper.getSystemService(WindowManager.class));
- }
-
- public void testGetAssets() {
- assertSame(mContext.getAssets(), mContextWrapper.getAssets());
- }
-
- public void testGetResources() {
- assertSame(mContext.getResources(), mContextWrapper.getResources());
- }
-
- public void testStartInstrumentation() {
- // Use wrong name
- ComponentName cn = new ComponentName("com.android",
- "com.android.content.FalseLocalSampleInstrumentation");
- assertNotNull(cn);
- assertNotNull(mContextWrapper);
- // If the target instrumentation is wrong, the function should return false.
- assertFalse(mContextWrapper.startInstrumentation(cn, null, null));
- }
-
- private void bindExpectResult(Context contextWrapper, Intent service)
- throws InterruptedException {
- if (service == null) {
- fail("No service created!");
- }
- TestConnection conn = new TestConnection(true, false);
-
- contextWrapper.bindService(service, conn, Context.BIND_AUTO_CREATE);
- contextWrapper.startService(service);
-
- // Wait for a short time, so the service related operations could be
- // working.
- synchronized (this) {
- wait(2500);
- }
- // Test stop Service
- assertTrue(contextWrapper.stopService(service));
- contextWrapper.unbindService(conn);
-
- synchronized (this) {
- wait(1000);
- }
- }
-
- private interface Condition {
- public boolean onCondition();
- }
-
- private synchronized void waitForCondition(Condition con) throws InterruptedException {
- // check the condition every 1 second until the condition is fulfilled
- // and wait for 3 seconds at most
- for (int i = 0; !con.onCondition() && i <= 3; i++) {
- wait(1000);
- }
- }
-
- private void waitForReceiveBroadCast(final ResultReceiver receiver)
- throws InterruptedException {
- Condition con = new Condition() {
- public boolean onCondition() {
- return receiver.hasReceivedBroadCast();
- }
- };
- waitForCondition(con);
- }
-
- private void waitForFilteredIntent(ContextWrapper contextWrapper, final String action)
- throws InterruptedException {
- contextWrapper.sendBroadcast(new Intent(action), null);
-
- synchronized (mLockObj) {
- mLockObj.wait(BROADCAST_TIMEOUT);
- }
- }
-
+ // TODO: this mock seems unnecessary. Remove it, and just use ContextWrapper?
private static final class MockContextWrapper extends ContextWrapper {
public MockContextWrapper(Context base) {
super(base);
@@ -843,84 +78,4 @@
super.attachBaseContext(base);
}
}
-
- private final class TestBroadcastReceiver extends BroadcastReceiver {
- boolean mHadReceivedBroadCast;
- boolean mIsOrderedBroadcasts;
-
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (this) {
- if (mIsOrderedBroadcasts) {
- setResultCode(3);
- setResultData(ACTUAL_RESULT);
- }
-
- Bundle map = getResultExtras(false);
- if (map != null) {
- map.remove(KEY_REMOVED);
- map.putString(KEY_ADDED, VALUE_ADDED);
- }
- mHadReceivedBroadCast = true;
- this.notifyAll();
- }
-
- synchronized (mLockObj) {
- mLockObj.notify();
- }
- }
-
- boolean hadReceivedBroadCast() {
- return mHadReceivedBroadCast;
- }
-
- void reset(){
- mHadReceivedBroadCast = false;
- }
- }
-
- private class FilteredReceiver extends BroadcastReceiver {
- private boolean mHadReceivedBroadCast1 = false;
- private boolean mHadReceivedBroadCast2 = false;
-
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (MOCK_ACTION1.equals(action)) {
- mHadReceivedBroadCast1 = true;
- } else if (MOCK_ACTION2.equals(action)) {
- mHadReceivedBroadCast2 = true;
- }
-
- synchronized (mLockObj) {
- mLockObj.notify();
- }
- }
-
- public boolean hadReceivedBroadCast1() {
- return mHadReceivedBroadCast1;
- }
-
- public boolean hadReceivedBroadCast2() {
- return mHadReceivedBroadCast2;
- }
-
- public void reset(){
- mHadReceivedBroadCast1 = false;
- mHadReceivedBroadCast2 = false;
- }
- }
-
- private class TestConnection implements ServiceConnection {
- public TestConnection(boolean expectDisconnect, boolean setReporter) {
- }
-
- void setMonitor(boolean v) {
- }
-
- public void onServiceConnected(ComponentName name, IBinder service) {
- }
-
- public void onServiceDisconnected(ComponentName name) {
- }
- }
}
diff --git a/tests/tests/content/src/android/content/cts/MockContextWrapperService.java b/tests/tests/content/src/android/content/cts/MockContextService.java
similarity index 94%
rename from tests/tests/content/src/android/content/cts/MockContextWrapperService.java
rename to tests/tests/content/src/android/content/cts/MockContextService.java
index ef4b09a..f634f68 100644
--- a/tests/tests/content/src/android/content/cts/MockContextWrapperService.java
+++ b/tests/tests/content/src/android/content/cts/MockContextService.java
@@ -25,11 +25,9 @@
import android.os.Message;
/**
- * This class is used for {@link ContextWrapper}
- *
- * @see ContextWrapperTest
+ * This class is used for {@link ContextTest}.
*/
-public class MockContextWrapperService extends Service {
+public class MockContextService extends Service {
private static boolean mHadCalledOnBind = false;
private static boolean mHadCalledOnUnbind = false;
private static boolean mHadCalledOnStart = false;
diff --git a/tests/tests/content/src/android/content/cts/ResultReceiver.java b/tests/tests/content/src/android/content/cts/ResultReceiver.java
index 1b80774..8b9cf67 100644
--- a/tests/tests/content/src/android/content/cts/ResultReceiver.java
+++ b/tests/tests/content/src/android/content/cts/ResultReceiver.java
@@ -21,13 +21,11 @@
import android.content.Intent;
/**
- * This class is used for testing android.content.ContentWrapper.
- *
- * @see ContextWrapperTest
+ * This class is used for {@link ContextTest}.
*/
public class ResultReceiver extends BroadcastReceiver {
public static final String MOCK_ACTION =
- "android.content.cts.ContextWrapperTest.BROADCAST_RESULT";
+ "android.content.cts.ContextTest.BROADCAST_RESULT";
private boolean mReceivedBroadCast;
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index edc7924..7fd9e0f 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -18,22 +18,37 @@
import android.content.cts.R;
+import static android.content.pm.ApplicationInfo.FLAG_HAS_CODE;
+import static android.content.pm.ApplicationInfo.FLAG_INSTALLED;
+import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+import static android.content.pm.PackageManager.GET_ACTIVITIES;
+import static android.content.pm.PackageManager.GET_META_DATA;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import static android.content.pm.PackageManager.GET_PROVIDERS;
+import static android.content.pm.PackageManager.GET_RECEIVERS;
+import static android.content.pm.PackageManager.GET_SERVICES;
+
+import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
import android.test.AndroidTestCase;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@@ -45,6 +60,8 @@
public class PackageManagerTest extends AndroidTestCase {
private PackageManager mPackageManager;
private static final String PACKAGE_NAME = "android.content.cts";
+ private static final String CONTENT_PKG_NAME = "android.content.cts";
+ private static final String APPLICATION_NAME = "android.content.cts.MockApplication";
private static final String ACTIVITY_ACTION_NAME = "android.intent.action.PMTEST";
private static final String MAIN_ACTION_NAME = "android.intent.action.MAIN";
private static final String SERVICE_ACTION_NAME =
@@ -55,6 +72,8 @@
private static final String SERVICE_NAME = "android.content.pm.cts.TestPmService";
private static final String RECEIVER_NAME = "android.content.pm.cts.PmTestReceiver";
private static final String INSTRUMENT_NAME = "android.content.pm.cts.TestPmInstrumentation";
+ private static final String CALL_ABROAD_PERMISSION_NAME =
+ "android.content.cts.CALL_ABROAD_PERMISSION";
private static final String PROVIDER_NAME = "android.content.cts.MockContentProvider";
private static final String PERMISSIONGROUP_NAME = "android.permission-group.COST_MONEY";
@@ -110,7 +129,7 @@
String testPermissionsGroup = "android.permission-group.COST_MONEY";
List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup(
testPermissionsGroup, PackageManager.GET_META_DATA);
- checkPermissionInfoName("android.content.cts.CALL_ABROAD_PERMISSION", permissions);
+ checkPermissionInfoName(CALL_ABROAD_PERMISSION_NAME, permissions);
ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 0);
List<ProviderInfo> providers = mPackageManager.queryContentProviders(PACKAGE_NAME,
@@ -515,4 +534,111 @@
assertEquals(null, result[1]);
assertEquals("com.android.cts.ctsshim", result[2]);
}
+
+ public void testGetInstalledPackages() throws Exception {
+ List<PackageInfo> pkgs = mPackageManager.getInstalledPackages(GET_META_DATA
+ | GET_PERMISSIONS | GET_ACTIVITIES | GET_PROVIDERS | GET_SERVICES | GET_RECEIVERS);
+
+ PackageInfo pkgInfo = findPackageOrFail(pkgs, PACKAGE_NAME);
+
+ // Check metadata
+ ApplicationInfo appInfo = pkgInfo.applicationInfo;
+ assertEquals(APPLICATION_NAME, appInfo.name);
+ assertEquals("Android TestCase", appInfo.loadLabel(mPackageManager));
+ assertEquals(PACKAGE_NAME, appInfo.packageName);
+ assertTrue(appInfo.enabled);
+ // The process name defaults to the package name when not set.
+ assertEquals(PACKAGE_NAME, appInfo.processName);
+ assertEquals(0, appInfo.flags & FLAG_SYSTEM);
+ assertEquals(FLAG_INSTALLED, appInfo.flags & FLAG_INSTALLED);
+ assertEquals(FLAG_HAS_CODE, appInfo.flags & FLAG_HAS_CODE);
+
+ // Check required permissions
+ List<String> requestedPermissions = Arrays.asList(pkgInfo.requestedPermissions);
+ assertThat(requestedPermissions).containsAllOf(
+ "android.permission.MANAGE_ACCOUNTS",
+ "android.permission.ACCESS_NETWORK_STATE",
+ "android.content.cts.permission.TEST_GRANTED");
+
+ // Check declared permissions
+ PermissionInfo declaredPermission = (PermissionInfo) findPackageItemOrFail(
+ pkgInfo.permissions, CALL_ABROAD_PERMISSION_NAME);
+ assertEquals("Call abroad", declaredPermission.loadLabel(mPackageManager));
+ assertEquals(PERMISSIONGROUP_NAME, declaredPermission.group);
+ assertEquals(PermissionInfo.PROTECTION_NORMAL, declaredPermission.protectionLevel);
+
+ // Check activities
+ ActivityInfo activity = findPackageItemOrFail(pkgInfo.activities, ACTIVITY_NAME);
+ assertTrue(activity.enabled);
+ assertTrue(activity.exported); // Has intent filters - export by default.
+ assertEquals(PACKAGE_NAME, activity.taskAffinity);
+ assertEquals(ActivityInfo.LAUNCH_SINGLE_TOP, activity.launchMode);
+
+ // Check services
+ ServiceInfo service = findPackageItemOrFail(pkgInfo.services, SERVICE_NAME);
+ assertTrue(service.enabled);
+ assertTrue(service.exported); // Has intent filters - export by default.
+ assertEquals(PACKAGE_NAME, service.packageName);
+ assertEquals(CALL_ABROAD_PERMISSION_NAME, service.permission);
+
+ // Check ContentProviders
+ ProviderInfo provider = findPackageItemOrFail(pkgInfo.providers, PROVIDER_NAME);
+ assertTrue(provider.enabled);
+ assertFalse(provider.exported); // Don't export by default.
+ assertEquals(PACKAGE_NAME, provider.packageName);
+ assertEquals("ctstest", provider.authority);
+
+ // Check Receivers
+ ActivityInfo receiver = findPackageItemOrFail(pkgInfo.receivers, RECEIVER_NAME);
+ assertTrue(receiver.enabled);
+ assertTrue(receiver.exported); // Has intent filters - export by default.
+ assertEquals(PACKAGE_NAME, receiver.packageName);
+ }
+
+ // Tests that other packages can be queried.
+ public void testGetInstalledPackages_OtherPackages() throws Exception {
+ List<PackageInfo> pkgInfos = mPackageManager.getInstalledPackages(0);
+
+ // Check a normal package.
+ PackageInfo pkgInfo = findPackageOrFail(pkgInfos, "com.android.cts.stub"); // A test package
+ assertEquals(0, pkgInfo.applicationInfo.flags & FLAG_SYSTEM);
+
+ // Check a system package.
+ pkgInfo = findPackageOrFail(pkgInfos, "android");
+ assertEquals(FLAG_SYSTEM, pkgInfo.applicationInfo.flags & FLAG_SYSTEM);
+ }
+
+ public void testGetInstalledApplications() throws Exception {
+ List<ApplicationInfo> apps = mPackageManager.getInstalledApplications(GET_META_DATA);
+
+ ApplicationInfo app = findPackageItemOrFail(
+ apps.toArray(new ApplicationInfo[] {}), APPLICATION_NAME);
+
+ assertEquals(APPLICATION_NAME, app.name);
+ assertEquals("Android TestCase", app.loadLabel(mPackageManager));
+ assertEquals(PACKAGE_NAME, app.packageName);
+ assertTrue(app.enabled);
+ // The process name defaults to the package name when not set.
+ assertEquals(PACKAGE_NAME, app.processName);
+ }
+
+ private PackageInfo findPackageOrFail(List<PackageInfo> pkgInfos, String pkgName) {
+ for (PackageInfo pkgInfo : pkgInfos) {
+ if (pkgName.equals(pkgInfo.packageName)) {
+ return pkgInfo;
+ }
+ }
+ fail("Package not found with name " + pkgName);
+ return null;
+ }
+
+ private <T extends PackageItemInfo> T findPackageItemOrFail(T[] items, String name) {
+ for (T item : items) {
+ if (name.equals(item.name)) {
+ return item;
+ }
+ }
+ fail("Package item not found with name " + name);
+ return null;
+ }
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
index 7645e25..2ea6e16 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
@@ -355,13 +355,15 @@
ColorSpace cs = b.getColorSpace();
assertNotNull(cs);
assertSame(ColorSpace.get(ColorSpace.Named.DISPLAY_P3), cs);
-
+ assertTrue(b.isMutable());
verifySetPixel(b, newColor, expectedColor);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth() / 2, b.getHeight() / 2);
+ assertTrue(b.isMutable());
verifySetPixel(b, newColor, expectedColor);
b = Bitmap.createScaledBitmap(b, b.getWidth() / 2, b.getHeight() / 2, true);
+ assertTrue(b.isMutable());
verifySetPixel(b, newColor, expectedColor);
} catch (IOException e) {
fail();
@@ -370,6 +372,7 @@
private static void verifySetPixel(@NonNull Bitmap b,
@ColorInt int newColor, @ColorInt int expectedColor) {
+ assertTrue(b.isMutable());
b.setPixel(0, 0, newColor);
ByteBuffer dst = ByteBuffer.allocate(b.getByteCount());
@@ -399,9 +402,11 @@
verifySetPixels(b, newColor, expectedColor);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth() / 2, b.getHeight() / 2);
+ assertTrue(b.isMutable());
verifySetPixels(b, newColor, expectedColor);
b = Bitmap.createScaledBitmap(b, b.getWidth() / 2, b.getHeight() / 2, true);
+ assertTrue(b.isMutable());
verifySetPixels(b, newColor, expectedColor);
} catch (IOException e) {
fail();
@@ -410,6 +415,7 @@
private static void verifySetPixels(@NonNull Bitmap b,
@ColorInt int newColor, @ColorInt int expectedColor) {
+ assertTrue(b.isMutable());
int[] pixels = new int[b.getWidth() * b.getHeight()];
Arrays.fill(pixels, newColor);
b.setPixels(pixels, 0, b.getWidth(), 0, 0, b.getWidth(), b.getHeight());
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRGBAF16Test.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRGBAF16Test.java
index 02c9425..6b9eb5a 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRGBAF16Test.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRGBAF16Test.java
@@ -25,6 +25,7 @@
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -107,9 +108,9 @@
@Test
public void testGetPixel() {
// Opaque pixels from opaque bitmap
- assertEquals(0xff0f131f, mOpaqueBitmap.getPixel(0, 0));
- assertEquals(0xff0f1421, mOpaqueBitmap.getPixel(1, 0));
- assertEquals(0xff101523, mOpaqueBitmap.getPixel(2, 0));
+ validatePixel(0xff0f131f, mOpaqueBitmap.getPixel(0, 0));
+ validatePixel(0xff0f1421, mOpaqueBitmap.getPixel(1, 0));
+ validatePixel(0xff101523, mOpaqueBitmap.getPixel(2, 0));
// Opaque pixels from transparent bitmap
assertEquals(0xffff0000, mTransparentBitmap.getPixel(0, 0));
@@ -148,4 +149,11 @@
Bitmap b = mask.copy(Config.RGBA_F16, false);
assertNotNull(b);
}
+
+ private void validatePixel(int expected, int actual) {
+ assertEquals(Color.alpha(expected), Color.alpha(actual));
+ assertEquals(Color.red(expected), Color.red(actual), 1);
+ assertEquals(Color.green(expected), Color.green(actual), 1);
+ assertEquals(Color.blue(expected), Color.blue(actual), 1);
+ }
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 1aec304..5289726 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -30,8 +30,10 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorSpace;
+import android.graphics.ColorSpace.Named;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Picture;
import android.os.Debug;
import android.os.Parcel;
import android.os.StrictMode;
@@ -207,8 +209,10 @@
public void testCreateBitmap1() {
int[] colors = createColors(100);
Bitmap bitmap = Bitmap.createBitmap(colors, 10, 10, Config.RGB_565);
+ assertFalse(bitmap.isMutable());
Bitmap ret = Bitmap.createBitmap(bitmap);
assertNotNull(ret);
+ assertFalse(ret.isMutable());
assertEquals(10, ret.getWidth());
assertEquals(10, ret.getHeight());
assertEquals(Config.RGB_565, ret.getConfig());
@@ -223,8 +227,10 @@
public void testCreateBitmap2() {
// special case: output bitmap is equal to the input bitmap
mBitmap = Bitmap.createBitmap(new int[100 * 100], 100, 100, Config.ARGB_8888);
+ assertFalse(mBitmap.isMutable()); // createBitmap w/ colors should be immutable
Bitmap ret = Bitmap.createBitmap(mBitmap, 0, 0, 100, 100);
assertNotNull(ret);
+ assertFalse(ret.isMutable()); // createBitmap from subset should be immutable
assertTrue(mBitmap.equals(ret));
//normal case
@@ -277,19 +283,33 @@
mBitmap = Bitmap.createBitmap(new int[100 * 100], 100, 100, Config.ARGB_8888);
Bitmap ret = Bitmap.createBitmap(mBitmap, 0, 0, 100, 100, null, false);
assertNotNull(ret);
+ assertFalse(ret.isMutable()); // subset should be immutable
assertTrue(mBitmap.equals(ret));
// normal case
mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
ret = Bitmap.createBitmap(mBitmap, 10, 10, 50, 50, new Matrix(), true);
+ assertTrue(ret.isMutable());
assertNotNull(ret);
assertFalse(mBitmap.equals(ret));
}
@Test
+ public void testCreateBitmapFromHardwareBitmap() {
+ Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot,
+ HARDWARE_OPTIONS);
+ assertEquals(Config.HARDWARE, hardwareBitmap.getConfig());
+
+ Bitmap ret = Bitmap.createBitmap(hardwareBitmap, 0, 0, 100, 100, null, false);
+ assertEquals(Config.HARDWARE, ret.getConfig());
+ assertFalse(ret.isMutable());
+ }
+
+ @Test
public void testCreateBitmap4() {
Bitmap ret = Bitmap.createBitmap(100, 200, Config.RGB_565);
assertNotNull(ret);
+ assertTrue(ret.isMutable());
assertEquals(100, ret.getWidth());
assertEquals(200, ret.getHeight());
assertEquals(Config.RGB_565, ret.getConfig());
@@ -306,6 +326,7 @@
public void testCreateBitmap_matrix() {
int[] colorArray = new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.BLACK };
Bitmap src = Bitmap.createBitmap(2, 2, Config.ARGB_8888);
+ assertTrue(src.isMutable());
src.setPixels(colorArray,0, 2, 0, 0, 2, 2);
// baseline
@@ -313,21 +334,25 @@
// null
Bitmap dst = Bitmap.createBitmap(src, 0, 0, 2, 2, null, false);
+ assertTrue(dst.isMutable());
verify2x2BitmapContents(colorArray, dst);
// identity matrix
Matrix matrix = new Matrix();
dst = Bitmap.createBitmap(src, 0, 0, 2, 2, matrix, false);
+ assertTrue(dst.isMutable());
verify2x2BitmapContents(colorArray, dst);
// big scale - only red visible
matrix.setScale(10, 10);
dst = Bitmap.createBitmap(src, 0, 0, 2, 2, matrix, false);
+ assertTrue(dst.isMutable());
verify2x2BitmapContents(new int[] { Color.RED, Color.RED, Color.RED, Color.RED }, dst);
// rotation
matrix.setRotate(90);
dst = Bitmap.createBitmap(src, 0, 0, 2, 2, matrix, false);
+ assertTrue(dst.isMutable());
verify2x2BitmapContents(
new int[] { Color.BLUE, Color.RED, Color.BLACK, Color.GREEN }, dst);
}
@@ -379,6 +404,7 @@
// normal case
Bitmap ret = Bitmap.createBitmap(colors, 5, 10, 10, 5, Config.RGB_565);
assertNotNull(ret);
+ assertFalse(ret.isMutable());
assertEquals(10, ret.getWidth());
assertEquals(5, ret.getHeight());
assertEquals(Config.RGB_565, ret.getConfig());
@@ -409,8 +435,26 @@
assertEquals(metrics.densityDpi, bitmap.getDensity());
int[] colors = createColors(100);
- assertNotNull(Bitmap.createBitmap(metrics, colors, 0, 10, 10, 10, Config.ARGB_8888));
- assertNotNull(Bitmap.createBitmap(metrics, colors, 10, 10, Config.ARGB_8888));
+ bitmap = Bitmap.createBitmap(metrics, colors, 0, 10, 10, 10, Config.ARGB_8888);
+ assertNotNull(bitmap);
+ assertFalse(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(metrics, colors, 10, 10, Config.ARGB_8888);
+ assertNotNull(bitmap);
+ assertFalse(bitmap.isMutable());
+ }
+
+ @Test
+ public void testCreateBitmap_noDisplayMetrics_mutable() {
+ Bitmap bitmap;
+ bitmap = Bitmap.createBitmap(10, 10, Config.ARGB_8888);
+ assertTrue(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(10, 10, Config.ARGB_8888, true);
+ assertTrue(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(10, 10, Config.ARGB_8888, true, ColorSpace.get(Named.SRGB));
+ assertTrue(bitmap.isMutable());
}
@Test
@@ -430,12 +474,51 @@
}
@Test
+ public void testCreateBitmap_noDisplayMetrics_immutable() {
+ int[] colors = createColors(100);
+ Bitmap bitmap;
+ bitmap = Bitmap.createBitmap(colors, 0, 10, 10, 10, Config.ARGB_8888);
+ assertFalse(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(colors, 10, 10, Config.ARGB_8888);
+ assertFalse(bitmap.isMutable());
+ }
+
+ @Test
+ public void testCreateBitmap_Picture_immutable() {
+ Picture picture = new Picture();
+ Canvas canvas = picture.beginRecording(200, 100);
+
+ Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ p.setColor(0x88FF0000);
+ canvas.drawCircle(50, 50, 40, p);
+
+ p.setColor(Color.GREEN);
+ p.setTextSize(30);
+ canvas.drawText("Pictures", 60, 60, p);
+ picture.endRecording();
+
+ Bitmap bitmap;
+ bitmap = Bitmap.createBitmap(picture);
+ assertFalse(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(picture, 100, 100, Config.HARDWARE);
+ assertFalse(bitmap.isMutable());
+
+ bitmap = Bitmap.createBitmap(picture, 100, 100, Config.ARGB_8888);
+ assertFalse(bitmap.isMutable());
+ }
+
+ @Test
public void testCreateScaledBitmap() {
mBitmap = Bitmap.createBitmap(100, 200, Config.RGB_565);
+ assertTrue(mBitmap.isMutable());
Bitmap ret = Bitmap.createScaledBitmap(mBitmap, 50, 100, false);
assertNotNull(ret);
assertEquals(50, ret.getWidth());
assertEquals(100, ret.getHeight());
+ assertTrue(ret.isMutable());
}
@Test
@@ -1457,6 +1540,14 @@
nValidateNdkAccessAfterRecycle(bitmap);
}
+ @Test
+ public void bitmapIsMutable() {
+ Bitmap b = Bitmap.createBitmap(10, 10, Config.ARGB_8888);
+ assertTrue("CreateBitmap w/ params should be mutable", b.isMutable());
+ assertTrue("CreateBitmap from bitmap should be mutable",
+ Bitmap.createBitmap(b).isMutable());
+ }
+
private void runGcAndFinalizersSync() {
final CountDownLatch fence = new CountDownLatch(1);
new Object() {
diff --git a/tests/tests/graphics/src/android/graphics/cts/PictureTest.java b/tests/tests/graphics/src/android/graphics/cts/PictureTest.java
index d83eecf..d566b41 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PictureTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PictureTest.java
@@ -34,9 +34,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PictureTest {
@@ -49,7 +46,6 @@
// In particular, this test verifies that, in the following situations,
// the created picture (effectively) has balanced saves and restores:
// - copy constructed picture from actively recording picture
- // - writeToStream/createFromStream created picture from actively recording picture
// - actively recording picture after draw call
@Test
public void testSaveRestoreBalance() {
@@ -65,17 +61,6 @@
assertEquals(expectedSaveCount, canvas.getSaveCount());
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- original.writeToStream(bout);
-
- assertEquals(expectedSaveCount, canvas.getSaveCount());
-
- Picture serialized = Picture.createFromStream(new ByteArrayInputStream(bout.toByteArray()));
- // The serialization/deserialization process will balance the saves and restores
- verifyBalance(serialized);
-
- assertEquals(expectedSaveCount, canvas.getSaveCount());
-
Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
Canvas drawDest = new Canvas(bitmap);
original.draw(drawDest);
@@ -118,7 +103,6 @@
@Test
public void testPicture() {
Picture picture = new Picture();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
assertNotNull(canvas);
@@ -131,16 +115,6 @@
verifySize(picture);
verifyBitmap(bitmap);
- picture.writeToStream(bout);
- picture = Picture.createFromStream(new ByteArrayInputStream(bout.toByteArray()));
-
- // create a new Canvas with a new bitmap
- bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
- canvas = new Canvas(bitmap);
- picture.draw(canvas);
- verifySize(picture);
- verifyBitmap(bitmap);
-
Picture pic = new Picture(picture);
bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
index ee34254..675f15c 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorDrawableTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import android.content.res.Resources;
@@ -148,6 +149,15 @@
}
@Test
+ public void testGetColorFilter() {
+ final ColorDrawable d = new ColorDrawable(Color.WHITE);
+ PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(Color.BLACK, Mode.SRC_OVER);
+ d.setColorFilter(colorFilter);
+
+ assertSame(colorFilter, d.getColorFilter());
+ }
+
+ @Test
public void testSetTint() {
final ColorDrawable d = new ColorDrawable(Color.WHITE);
assertEquals(Color.WHITE, DrawableTestUtils.getPixel(d, 0, 0));
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
index 4a05376..fb3190b 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
@@ -367,9 +367,9 @@
gradientDrawable.setColor(color);
assertEquals("Color was set to RED", color, gradientDrawable.getColor());
- color = null;
- gradientDrawable.setColor(color);
- assertEquals("Color was set to null (TRANSPARENT)", color, gradientDrawable.getColor());
+ gradientDrawable.setColor(null);
+ assertEquals("Color was set to null (TRANSPARENT)",
+ ColorStateList.valueOf(Color.TRANSPARENT), gradientDrawable.getColor());
}
@Test
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
index d563102..11f8fc5 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -373,7 +373,7 @@
a.setShape(new OvalShape());
ShapeDrawable b = (ShapeDrawable) a.getConstantState().newDrawable();
- assertSame(a.getShape(), b.getShape());
+ assertEquals(a.getShape(), b.getShape());
a.mutate();
assertNotNull(a.getShape());
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
index c96a1ca..a7b20c6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
@@ -30,6 +30,7 @@
import android.graphics.cts.R;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.graphics.drawable.DrawableContainer.DrawableContainerState;
import android.graphics.drawable.StateListDrawable;
@@ -332,6 +333,66 @@
}
@Test
+ public void testGetStateCount() {
+ StateListDrawable stateList = new StateListDrawable();
+ stateList.addState(new int[]{0}, new ColorDrawable(Color.RED));
+
+ assertEquals(1, stateList.getStateCount());
+
+ stateList.addState(new int[]{1}, new ColorDrawable(Color.GREEN));
+
+ assertEquals(2, stateList.getStateCount());
+
+ stateList.addState(new int[]{2}, new ColorDrawable(Color.BLUE));
+
+ assertEquals(3, stateList.getStateCount());
+ }
+
+ @Test
+ public void testGetStateDrawable() {
+ StateListDrawable stateList = new StateListDrawable();
+
+ ColorDrawable colorDrawable = new ColorDrawable(Color.RED);
+ int[] stateSet = new int[]{1};
+ stateList.addState(stateSet, colorDrawable);
+
+ Drawable drawable = stateList.getStateDrawable(0);
+ assertSame(colorDrawable, drawable);
+ }
+
+ @Test
+ public void testGetStateSet() {
+ StateListDrawable stateList = new StateListDrawable();
+
+ ColorDrawable colorDrawable = new ColorDrawable(Color.GREEN);
+ int[] stateSet = new int[]{0};
+
+ stateList.addState(stateSet, colorDrawable);
+ int[] resolvedStateSet = stateList.getStateSet(0);
+ assertEquals(stateSet, resolvedStateSet);
+ }
+
+ @Test
+ public void testGetStateDrawableIndex() {
+ StateListDrawable stateList = new StateListDrawable();
+
+ ColorDrawable drawable1 = new ColorDrawable(Color.CYAN);
+ ColorDrawable drawable2 = new ColorDrawable(Color.YELLOW);
+ ColorDrawable drawable3 = new ColorDrawable(Color.GREEN);
+ int[] stateSet1 = new int[]{42};
+ int[] stateSet2 = new int[]{27};
+ int[] stateSet3 = new int[]{57};
+
+ stateList.addState(stateSet1, drawable1);
+ stateList.addState(stateSet2, drawable2);
+ stateList.addState(stateSet3, drawable3);
+
+ assertEquals(0, stateList.getStateDrawableIndex(stateSet1));
+ assertEquals(1, stateList.getStateDrawableIndex(stateSet2));
+ assertEquals(2, stateList.getStateDrawableIndex(stateSet3));
+ }
+
+ @Test
public void testMutate() {
StateListDrawable d1 =
(StateListDrawable) mResources.getDrawable(R.drawable.statelistdrawable);
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index 4e8aaa7..f247e177 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -41,7 +41,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsHardwareTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/hardware/jni/Android.mk b/tests/tests/hardware/jni/Android.mk
index 0cd95e7..6df6667 100644
--- a/tests/tests/hardware/jni/Android.mk
+++ b/tests/tests/hardware/jni/Android.mk
@@ -30,7 +30,9 @@
LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
-LOCAL_CXX_STL := libc++_static
+LOCAL_NDK_STL_VARIANT := none
+
+LOCAL_SDK_VERSION := current
LOCAL_CLANG := true
diff --git a/tests/tests/hardware/jni/android_hardware_cts_HardwareBufferTest.cpp b/tests/tests/hardware/jni/android_hardware_cts_HardwareBufferTest.cpp
index c5b5c35..8df230f 100644
--- a/tests/tests/hardware/jni/android_hardware_cts_HardwareBufferTest.cpp
+++ b/tests/tests/hardware/jni/android_hardware_cts_HardwareBufferTest.cpp
@@ -20,7 +20,6 @@
#include <jni.h>
#include <android/hardware_buffer_jni.h>
-#include <utils/Errors.h>
#define LOG_TAG "HardwareBufferTest"
@@ -35,7 +34,9 @@
desc.usage = usage;
desc.format = format;
int res = AHardwareBuffer_allocate(&desc, &buffer);
- if (res == android::NO_ERROR) {
+
+ // TODO: Change this to res == NO_ERROR after b/77153085 is fixed
+ if (res == 0) {
return AHardwareBuffer_toHardwareBuffer(env, buffer);
} else {
return 0;
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
index 27ba081..0b7f7a0 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
@@ -39,8 +39,6 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import libcore.io.IoUtils;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -71,7 +69,7 @@
new ActivityTestRule<>(InputCtsActivity.class);
@Before
- public void setUp() throws Exception {
+ public void setUp() {
clearKeys();
clearMotions();
mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -80,8 +78,10 @@
}
@After
- public void tearDown() throws Exception {
- IoUtils.closeQuietly(mOutputStream);
+ public void tearDown() {
+ try {
+ mOutputStream.close();
+ } catch (IOException ignored) {}
}
/**
@@ -177,12 +177,14 @@
mMotions.clear();
}
- private void setupPipes() throws IOException {
+ private void setupPipes() {
UiAutomation ui = mInstrumentation.getUiAutomation();
ParcelFileDescriptor[] pipes = ui.executeShellCommandRw(HID_COMMAND);
mOutputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipes[1]);
- IoUtils.closeQuietly(pipes[0]); // hid command is write-only
+ try {
+ pipes[0].close(); // hid command is write-only
+ } catch (IOException ignored) {}
}
private String getEvents(int id) throws IOException {
@@ -201,6 +203,7 @@
return baos.toString();
}
+
private class InputListener implements InputCallback {
@Override
public void onKeyEvent(KeyEvent ev) {
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
index 72acf64..2c97759 100644
--- a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -42,6 +42,7 @@
private final static String VENDOR_CONFIG_FILE = "/vendor/etc/public.libraries.txt";
private final static String[] PUBLIC_SYSTEM_LIBRARIES = {
"libaaudio.so",
+ "libamidi.so",
"libandroid.so",
"libc.so",
"libcamera2ndk.so",
diff --git a/tests/tests/nativemidi/Android.mk b/tests/tests/nativemidi/Android.mk
new file mode 100755
index 0000000..5da14e4
--- /dev/null
+++ b/tests/tests/nativemidi/Android.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2018 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)
+
+#
+# NativeMidiEchoTest
+#
+include $(CLEAR_VARS)
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libnativemidi_jni
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_PACKAGE_NAME := CtsNativeMidiTestCases
+LOCAL_MULTILIB := both
+
+LOCAL_SDK_VERSION := current
+LOCAL_NDK_STL_VARIANT := c++_static
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/nativemidi/AndroidManifest.xml b/tests/tests/nativemidi/AndroidManifest.xml
new file mode 100755
index 0000000..5c42c52
--- /dev/null
+++ b/tests/tests/nativemidi/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 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="android.nativemidi.cts">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+ <uses-feature android:name="android.software.midi" android:required="true"/>
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+ <service android:name="NativeMidiEchoTestService"
+ android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
+ <intent-filter>
+ <action android:name="android.media.midi.MidiDeviceService" />
+ </intent-filter>
+ <meta-data android:name="android.media.midi.MidiDeviceService"
+ android:resource="@xml/echo_device_info" />
+ </service>
+
+ <activity android:name="android.nativemidi.cts.NativeMidiEchoTest"
+ android:label="NativeMidiEchoTest"/>
+ </application>
+
+ <!-- self-instrumenting test package. -->
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:label="CTS Native MIDI tests"
+ android:targetPackage="android.nativemidi.cts" >
+ <meta-data
+ android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+</manifest>
+
diff --git a/tests/tests/nativemidi/AndroidTest.xml b/tests/tests/nativemidi/AndroidTest.xml
new file mode 100644
index 0000000..3a4774a
--- /dev/null
+++ b/tests/tests/nativemidi/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<configuration description="Config for CTS MIDI test cases">
+ <option name="config-descriptor:metadata" key="component" value="media" />
+ <option name="test-suite-tag" value="cts" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsMidiTestCases.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.nativemidi.cts" />
+ <option name="runtime-hint" value="8m" />
+ </test>
+</configuration>
diff --git a/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java
new file mode 100644
index 0000000..1de9703
--- /dev/null
+++ b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2018 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.nativemidi.cts;
+
+import android.app.Activity;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.midi.MidiManager;
+import android.media.midi.MidiOutputPort;
+import android.media.midi.MidiDevice;
+import android.media.midi.MidiDevice.MidiConnection;
+import android.media.midi.MidiDeviceInfo;
+import android.media.midi.MidiDeviceInfo.PortInfo;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiInputPort;
+import android.media.midi.MidiReceiver;
+import android.media.midi.MidiSender;
+
+import android.os.Bundle;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.test.AndroidTestCase;
+
+import android.util.Log;
+
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+/*
+ * Test Class
+ */
+@RunWith(AndroidJUnit4.class)
+public class NativeMidiEchoTest {
+ private static final String TAG = "NativeMidiEchoTest";
+
+ public static final String TEST_MANUFACTURER = "AndroidCTS";
+ public static final String ECHO_PRODUCT = "NativeMidiEcho";
+
+ private static final long NANOS_PER_MSEC = 1000L * 1000L;
+
+ // This number seems excessively large and it is not clear if there is a linear
+ // relationship between the number of messages sent and the time required to send them
+ private static final int TIMEOUT_PER_MESSAGE_MS = 10;
+
+ // This timeout value is very generous.
+ private static final int TIMEOUT_OPEN_MSEC = 2000; // arbitrary
+
+ private Context mContext = InstrumentationRegistry.getContext();
+ private MidiManager mMidiManager;
+
+ private MidiDevice mEchoDevice;
+
+ private Random mRandom = new Random(1972941337);
+
+ // (Native code) attributes associated with a test/EchoServer instance.
+ private long mTestContext;
+
+ static {
+ System.loadLibrary("nativemidi_jni");
+ }
+
+ /*
+ * Helpers
+ */
+ private boolean hasMidiSupport() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_MIDI);
+ }
+
+ private byte[] generateRandomMessage(int len) {
+ byte[] buffer = new byte[len];
+ for(int index = 0; index < len; index++) {
+ buffer[index] = (byte)(mRandom.nextInt() & 0xFF);
+ }
+ return buffer;
+ }
+
+ private void generateRandomBufers(byte[][] buffers, long timestamps[], int numMessages) {
+ int messageLen;
+ int maxMessageLen = 128;
+ for(int buffIndex = 0; buffIndex < numMessages; buffIndex++) {
+ messageLen = (int)(mRandom.nextFloat() * (maxMessageLen-1)) + 1;
+ buffers[buffIndex] = generateRandomMessage(messageLen);
+ timestamps[buffIndex] = mRandom.nextLong();
+ }
+ }
+
+ private void compareMessages(byte[] buffer, long timestamp, NativeMidiMessage nativeMsg) {
+ Assert.assertEquals("byte count of message", buffer.length, nativeMsg.len);
+ Assert.assertEquals("timestamp in message", timestamp, nativeMsg.timestamp);
+
+ for (int index = 0; index < buffer.length; index++) {
+ Assert.assertEquals("message byte[" + index + "]", buffer[index] & 0x0FF,
+ nativeMsg.buffer[index] & 0x0FF);
+ }
+ }
+
+ /*
+ * Echo Server
+ */
+ // Listens for an asynchronous device open and notifies waiting foreground
+ // test.
+ class MyTestOpenCallback implements MidiManager.OnDeviceOpenedListener {
+ private volatile MidiDevice mDevice;
+
+ @Override
+ public synchronized void onDeviceOpened(MidiDevice device) {
+ mDevice = device;
+ notifyAll();
+ }
+
+ public synchronized MidiDevice waitForOpen(int msec)
+ throws InterruptedException {
+ long deadline = System.currentTimeMillis() + msec;
+ long timeRemaining = msec;
+ while (mDevice == null && timeRemaining > 0) {
+ wait(timeRemaining);
+ timeRemaining = deadline - System.currentTimeMillis();
+ }
+ return mDevice;
+ }
+ }
+
+ protected void setUpEchoServer() throws Exception {
+ Log.i(TAG, "++ setUpEchoServer()");
+ MidiDeviceInfo echoInfo = findEchoDevice();
+
+ // Open device.
+ MyTestOpenCallback callback = new MyTestOpenCallback();
+ mMidiManager.openDevice(echoInfo, callback, null);
+ mEchoDevice = callback.waitForOpen(TIMEOUT_OPEN_MSEC);
+ Assert.assertNotNull("could not open " + ECHO_PRODUCT, mEchoDevice);
+
+ // Query echo service directly to see if it is getting status updates.
+ NativeMidiEchoTestService echoService = NativeMidiEchoTestService.getInstance();
+
+ mTestContext = allocTestContext();
+ Assert.assertTrue("couldn't allocate test context.", mTestContext != 0);
+
+ // Open Device
+ int result = openNativeMidiDevice(mTestContext, mEchoDevice);
+ Assert.assertEquals("Bad open native MIDI device", 0, result);
+
+ // Open Input
+ result = startWritingMidi(mTestContext, 0/*mPortNumber*/);
+ Assert.assertEquals("Bad start writing (native) MIDI", 0, result);
+
+ // Open Output
+ result = startReadingMidi(mTestContext, 0/*mPortNumber*/);
+ Assert.assertEquals("Bad start Reading (native) MIDI", 0, result);
+ }
+
+ protected void tearDownEchoServer() throws IOException {
+ Log.i(TAG, "++ tearDownEchoServer()");
+ // Query echo service directly to see if it is getting status updates.
+ NativeMidiEchoTestService echoService = NativeMidiEchoTestService.getInstance();
+
+ int result;
+
+ // Stop inputs
+ result = stopReadingMidi(mTestContext);
+ Assert.assertEquals("Bad stop reading (native) MIDI", 0, result);
+
+ // Stop outputs
+ result = stopWritingMidi(mTestContext);
+ Assert.assertEquals("Bad stop writing (native) MIDI", 0, result);
+
+ // Close Device
+ result = closeNativeMidiDevice(mTestContext);
+ Assert.assertEquals("Bad close native MIDI device", 0, result);
+
+ freeTestContext(mTestContext);
+ mTestContext = 0;
+
+ mEchoDevice.close();
+ }
+
+ // Search through the available devices for the ECHO loop-back device.
+ protected MidiDeviceInfo findEchoDevice() {
+ MidiDeviceInfo[] infos = mMidiManager.getDevices();
+ MidiDeviceInfo echoInfo = null;
+ for (MidiDeviceInfo info : infos) {
+ Bundle properties = info.getProperties();
+ String manufacturer = (String) properties.get(
+ MidiDeviceInfo.PROPERTY_MANUFACTURER);
+
+ if (TEST_MANUFACTURER.equals(manufacturer)) {
+ String product = (String) properties.get(
+ MidiDeviceInfo.PROPERTY_PRODUCT);
+ if (ECHO_PRODUCT.equals(product)) {
+ echoInfo = info;
+ break;
+ }
+ }
+ }
+ Assert.assertNotNull("could not find " + ECHO_PRODUCT, echoInfo);
+ return echoInfo;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ Log.i(TAG, "++ setUp() mContext:" + mContext);
+ if (!hasMidiSupport()) {
+ Assert.assertTrue("FEATURE_MIDI Not Supported.", false);
+ return; // Not supported so don't test it.
+ }
+ mMidiManager = (MidiManager)mContext.getSystemService(Context.MIDI_SERVICE);
+ Assert.assertNotNull("Could not get the MidiManger.", mMidiManager);
+
+ setUpEchoServer();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ tearDownEchoServer();
+
+ Log.i(TAG, "++ tearDown()");
+ mMidiManager = null;
+ }
+
+ @Test
+ public void test_A_MidiManager() throws Exception {
+ Log.i(TAG, "++++ test_A_MidiManager() this:" + System.identityHashCode(this));
+
+ if (!hasMidiSupport()) {
+ return; // Nothing to test
+ }
+
+ Assert.assertNotNull("MidiManager not supported.", mMidiManager);
+
+ // There should be at least one device for the Echo server.
+ MidiDeviceInfo[] infos = mMidiManager.getDevices();
+ Assert.assertNotNull("device list was null", infos);
+ Assert.assertTrue("device list was empty", infos.length >= 1);
+
+ Log.i(TAG, "++++ test_A_MidiManager() - DONE");
+ }
+
+ @Test
+ public void test_B_SendData() throws Exception {
+ Log.i(TAG, "++++ test_B_SendData() this:" + System.identityHashCode(this));
+
+ Assert.assertEquals("Didn't start with 0 sends", 0, getNumSends(mTestContext));
+ Assert.assertEquals("Didn't start with 0 bytes sent", 0, getNumBytesSent(mTestContext));
+
+ final byte[] buffer = {
+ (byte) 0x93, 0x47, 0x52
+ };
+ long timestamp = 0x0123765489ABFEDCL;
+ writeMidi(mTestContext, buffer, 0, buffer.length);
+
+ Assert.assertTrue("Didn't get 1 send", getNumBytesSent(mTestContext) == buffer.length);
+ Assert.assertEquals("Didn't get right number of bytes sent",
+ buffer.length, getNumBytesSent(mTestContext));
+
+ Log.i(TAG, "++++ test_B_SendData() - DONE");
+ }
+
+ @Test
+ public void test_C_EchoSmallMessage() throws Exception {
+ Log.i(TAG, "++++ test_C_EchoSmallMessage() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ final byte[] buffer = {
+ (byte) 0x93, 0x47, 0x52
+ };
+ long timestamp = 0x0123765489ABFEDCL;
+
+ writeMidiWithTimestamp(mTestContext, buffer, 0, 0, timestamp); // should be a NOOP
+ writeMidiWithTimestamp(mTestContext, buffer, 0, buffer.length, timestamp);
+ writeMidiWithTimestamp(mTestContext, buffer, 0, 0, timestamp); // should be a NOOP
+
+ // Wait for message to pass quickly through echo service.
+ final int numMessages = 1;
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+ Assert.assertEquals("number of messages.",
+ numMessages, getNumReceivedMessages(mTestContext));
+
+ NativeMidiMessage message = getReceivedMessageAt(mTestContext, 0);
+ compareMessages(buffer, timestamp, message);
+
+ Log.i(TAG, "++++ test_C_EchoSmallMessage() - DONE");
+ }
+
+ @Test
+ public void test_D_EchoNMessages() throws Exception {
+ Log.i(TAG, "++++ test_D_EchoNMessages() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ int numMessages = 100;
+ byte[][] buffers = new byte[numMessages][];
+ long timestamps[] = new long[numMessages];
+ generateRandomBufers(buffers, timestamps, numMessages);
+
+ for(int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ writeMidiWithTimestamp(mTestContext, buffers[msgIndex], 0, buffers[msgIndex].length,
+ timestamps[msgIndex]);
+ }
+
+ // Wait for message to pass quickly through echo service.
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+
+ // correct number of messages
+ Assert.assertEquals("number of messages.",
+ numMessages, getNumReceivedMessages(mTestContext));
+
+ // correct data & order?
+ for(int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ NativeMidiMessage message = getReceivedMessageAt(mTestContext, msgIndex);
+ compareMessages(buffers[msgIndex], timestamps[msgIndex], message);
+ }
+
+ Log.i(TAG, "++++ test_D_EchoNMessages() - DONE");
+ }
+
+ @Test
+ public void test_E_FlushMessages() throws Exception {
+ Log.i(TAG, "++++ test_E_FlushMessages() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ int numMessages = 7;
+ byte[][] buffers = new byte[numMessages][];
+ long timestamps[] = new long[numMessages];
+ generateRandomBufers(buffers, timestamps, numMessages);
+
+ for(int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ writeMidiWithTimestamp(mTestContext, buffers[msgIndex], 0, buffers[msgIndex].length,
+ timestamps[msgIndex]);
+ }
+
+ // Wait for message to pass through echo service.
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+
+ int result = flushSentMessages(mTestContext);
+ Assert.assertEquals("flush messages failed", 0, result);
+
+ // correct number of messages
+ Assert.assertEquals("number of messages.",
+ numMessages, getNumReceivedMessages(mTestContext));
+
+ // correct data & order?
+ for(int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ NativeMidiMessage message = getReceivedMessageAt(mTestContext, msgIndex);
+ compareMessages(buffers[msgIndex], timestamps[msgIndex], message);
+ }
+
+ Log.i(TAG, "++++ test_E_FlushMessages() - DONE");
+ }
+
+ @Test
+ public void test_F_HugeMessage() throws Exception {
+ Log.i(TAG, "++++ test_F_HugeMessage() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ // Arbitrarily large message.
+ int hugeMessageLen = 1024 * 10;
+ byte[] buffer = generateRandomMessage(hugeMessageLen);
+ int result = writeMidi(mTestContext, buffer, 0, buffer.length);
+ Assert.assertEquals("Huge write failed.", hugeMessageLen, result);
+
+ int kindaHugeMessageLen = 1024 * 2;
+ buffer = generateRandomMessage(kindaHugeMessageLen);
+ result = writeMidi(mTestContext, buffer, 0, buffer.length);
+ Assert.assertEquals("Kinda big write failed.", kindaHugeMessageLen, result);
+
+ Log.i(TAG, "++++ test_F_HugeMessage() - DONE");
+ }
+
+ /**
+ * Check a large timeout for the echoed messages to come through. If they exceed this
+ * or don't come through at all, something is wrong.
+ */
+ @Test
+ public void test_G_NativeEchoTime() throws Exception {
+ Log.i(TAG, "++++ test_G_NativeEchoTime() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ final int numMessages = 10;
+ final long maxLatencyNanos = 15 * NANOS_PER_MSEC; // generally < 3 msec on N6
+ byte[] buffer = { (byte) 0x93, 0, 64 };
+
+ // Send multiple messages in a burst.
+ for (int index = 0; index < numMessages; index++) {
+ buffer[1] = (byte) (60 + index);
+ writeMidiWithTimestamp(mTestContext, buffer, 0, buffer.length, System.nanoTime());
+ }
+
+ // Wait for messages to pass quickly through echo service.
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+ Assert.assertEquals("number of messages.",
+ numMessages, getNumReceivedMessages(mTestContext));
+
+ for (int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ NativeMidiMessage message = getReceivedMessageAt(mTestContext, msgIndex);
+ Assert.assertEquals("message index", (byte) (60 + msgIndex), message.buffer[1]);
+ long elapsedNanos = message.timeReceived - message.timestamp;
+ // If this test fails then there may be a problem with the thread scheduler
+ // or there may be kernel activity that is blocking execution at the user level.
+ Assert.assertTrue("MIDI round trip latency index:" + msgIndex
+ + " too large, " + elapsedNanos
+ + " nanoseconds " +
+ "timestamp:" + message.timestamp + " received:" + message.timeReceived,
+ (elapsedNanos < maxLatencyNanos));
+ }
+
+ Log.i(TAG, "++++ test_G_NativeEchoTime() - DONE");
+ }
+
+ @Test
+ public void test_H_EchoNMessages_PureNative() throws Exception {
+ Log.i(TAG, "++++ test_H_EchoNMessages_PureNative() this:" + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ int numMessages = 2;
+ byte[][] buffers = new byte[numMessages][];
+ long timestamps[] = new long[numMessages];
+ generateRandomBufers(buffers, timestamps, numMessages);
+
+ for(int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ writeMidiWithTimestamp(mTestContext, buffers[msgIndex], 0, buffers[msgIndex].length,
+ timestamps[msgIndex]);
+ }
+
+ // Wait for message to pass quickly through echo service.
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+
+ int result = matchNativeMessages(mTestContext);
+ Assert.assertEquals("Native Compare Test Failed", result, 0);
+
+ Log.i(TAG, "++++ test_H_EchoNMessages_PureNative() - DONE");
+ }
+
+ /**
+ * Check a large timeout for the echoed messages to come through. If they exceed this
+ * or don't come through at all, something is wrong.
+ */
+ @Test
+ public void test_I_NativeEchoTime_PureNative() throws Exception {
+ Log.i(TAG, "++++ test_I_NativeEchoTime_PureNative() this:"
+ + System.identityHashCode(this));
+ if (!hasMidiSupport()) {
+ return; // nothing to test
+ }
+
+ final int numMessages = 10;
+ final long maxLatencyNanos = 15 * NANOS_PER_MSEC; // generally < 3 msec on N6
+ byte[] buffer = { (byte) 0x93, 0, 64 };
+
+ // Send multiple messages in a burst.
+ for (int index = 0; index < numMessages; index++) {
+ buffer[1] = (byte) (60 + index);
+ writeMidiWithTimestamp(mTestContext, buffer, 0, buffer.length, System.nanoTime());
+ }
+
+ // Wait for messages to pass through echo service.
+ final int timeoutMs = TIMEOUT_PER_MESSAGE_MS * numMessages;
+ Thread.sleep(timeoutMs);
+ Assert.assertEquals("number of messages.",
+ numMessages, getNumReceivedMessages(mTestContext));
+
+ int result = checkNativeLatency(mTestContext, maxLatencyNanos);
+ Assert.assertEquals("failed pure native latency test.", 0, result);
+
+ Log.i(TAG, "++++ test_I_NativeEchoTime_PureNative() - DONE");
+ }
+
+ // Native Routines
+ public static native void initN();
+
+ public static native long allocTestContext();
+ public static native void freeTestContext(long context);
+
+ public native int openNativeMidiDevice(long ctx, MidiDevice device);
+ public native int closeNativeMidiDevice(long ctx);
+
+ public native int startReadingMidi(long ctx, int portNumber);
+ public native int stopReadingMidi(long ctx);
+
+ public native int startWritingMidi(long ctx, int portNumber);
+ public native int stopWritingMidi(long ctx);
+
+ public native int writeMidi(long ctx, byte[] data, int offset, int length);
+ public native int writeMidiWithTimestamp(long ctx, byte[] data, int offset, int length,
+ long timestamp);
+ public native int flushSentMessages(long ctx);
+
+ // Status - Counters
+ public native int getNumSends(long ctx);
+ public native int getNumBytesSent(long ctx);
+ public native int getNumReceives(long ctx);
+ public native int getNumBytesReceived(long ctx);
+
+ // Status - Received Messages
+ public native int getNumReceivedMessages(long ctx);
+ public native NativeMidiMessage getReceivedMessageAt(long ctx, int index);
+
+ // Pure Native Checks
+ public native int matchNativeMessages(long ctx);
+ public native int checkNativeLatency(long ctx, long maxLatencyNanos);
+}
diff --git a/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTestService.java b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTestService.java
new file mode 100644
index 0000000..1984419
--- /dev/null
+++ b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTestService.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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.nativemidi.cts;
+
+import android.content.Context;
+
+import android.media.midi.MidiDeviceService;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiManager;
+import android.media.midi.MidiReceiver;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Virtual MIDI Device that copies its input to its output.
+ * This is a Java Service that is used to test the Native MIDI API.
+ */
+
+public class NativeMidiEchoTestService extends MidiDeviceService {
+ private static final String TAG = "NativeMidiEchoTestService";
+
+ // Other apps will write to this port.
+ private MidiReceiver mInputReceiver = new MyReceiver();
+ // This app will copy the data to this port.
+ private MidiReceiver mOutputReceiver;
+ private static NativeMidiEchoTestService mInstance;
+
+ // These are public so we can easily read them from CTS test.
+ public int statusChangeCount;
+ public boolean inputOpened;
+ public int outputOpenCount;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mInstance = this;
+ MidiManager midiManager = (MidiManager)getSystemService(Context.MIDI_SERVICE);
+ if (midiManager == null) {
+ Log.e(TAG, "No MIDI Manager!");
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ }
+
+ // For CTS testing, so I can read test fields.
+ public static NativeMidiEchoTestService getInstance() {
+ return mInstance;
+ }
+
+ @Override
+ public MidiReceiver[] onGetInputPortReceivers() {
+ return new MidiReceiver[] { mInputReceiver };
+ }
+
+ class MyReceiver extends MidiReceiver {
+ @Override
+ public void onSend(byte[] data, int offset, int count, long timestamp)
+ throws IOException {
+ if (mOutputReceiver == null) {
+ mOutputReceiver = getOutputPortReceivers()[0];
+ }
+ // Copy input to output.
+ mOutputReceiver.send(data, offset, count, timestamp);
+ }
+ }
+
+ @Override
+ public void onDeviceStatusChanged(MidiDeviceStatus status) {
+ statusChangeCount++;
+ inputOpened = status.isInputPortOpen(0);
+ outputOpenCount = status.getOutputPortOpenCount(0);
+ }
+}
diff --git a/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiMessage.java b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiMessage.java
new file mode 100644
index 0000000..d8186fe
--- /dev/null
+++ b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiMessage.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.nativemidi.cts;
+
+public class NativeMidiMessage {
+ public static final int AMIDI_PACKET_SIZE = 1024;
+ public static final int AMIDI_PACKET_OVERHEAD = 9;
+ public static final int AMIDI_BUFFER_SIZE = AMIDI_PACKET_SIZE - AMIDI_PACKET_OVERHEAD;
+
+ public int opcode;
+ public byte[] buffer = new byte[AMIDI_BUFFER_SIZE];
+ public int len;
+ public long timestamp;
+ public long timeReceived;
+
+ public NativeMidiMessage() {}
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{opcode:" + opcode + " [len:" + len + "|");
+ for(int index = 0; index < len; index++) {
+ sb.append("0x" + Integer.toHexString(buffer[index] & 0x00FF));
+ if (index < len - 1) {
+ sb.append(" ");
+ }
+ }
+ sb.append("] timestamp:" + Long.toHexString(timestamp));
+
+ return sb.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/nativemidi/jni/Android.mk b/tests/tests/nativemidi/jni/Android.mk
new file mode 100644
index 0000000..bb62dec
--- /dev/null
+++ b/tests/tests/nativemidi/jni/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2018 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_MODULE := libnativemidi_jni
+LOCAL_MULTILIB := both
+
+LOCAL_SRC_FILES := native-lib.cpp
+
+LOCAL_CFLAGS += -Wall -Wextra -Werror -O0
+
+LOCAL_SDK_VERSION := current
+LOCAL_NDK_STL_VARIANT := c++_static
+
+LOCAL_SHARED_LIBRARIES := libamidi liblog
+LOCAL_WHOLE_STATIC_LIBRARIES := libnativetesthelper_jni
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/nativemidi/jni/native-lib.cpp b/tests/tests/nativemidi/jni/native-lib.cpp
new file mode 100644
index 0000000..e68859c
--- /dev/null
+++ b/tests/tests/nativemidi/jni/native-lib.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <atomic>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string>
+#include <thread>
+#include <time.h>
+#include <vector>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NativeMidiManager-JNI"
+#include <android/log.h>
+
+#include <jni.h>
+
+#include <amidi/midi.h>
+
+extern "C" {
+
+/*
+ * Structures for storing data flowing through the echo server.
+ */
+#define SIZE_DATABUFFER 256
+/*
+ * Received Messages
+ */
+typedef struct {
+ std::unique_ptr<uint8_t[]> dataBuff;
+ size_t numDataBytes;
+ int32_t opCode;
+ int64_t timestamp;
+ int64_t timeReceived;
+} ReceivedMessageRecord;
+
+/*
+ * Sent Messages
+ */
+typedef struct {
+ std::unique_ptr<uint8_t[]> dataBuff;
+ size_t numDataBytes;
+ int64_t timestamp;
+ long timeSent;
+} SentMessageRecord;
+
+/*
+ * Context
+ * Holds the state of a given test and native MIDI I/O setup for that test.
+ * NOTE: There is one of these per test (and therefore unique to each test thread).
+ */
+class TestContext {
+private:
+ // counters
+ std::atomic<int> mNumSends;
+ std::atomic<int> mNumBytesSent;
+ std::atomic<int> mNumReceives;
+ std::atomic<int> mNumBytesReceived;
+
+ std::vector<ReceivedMessageRecord> mReceivedMsgs;
+ std::vector<SentMessageRecord> mSentMsgs;
+
+ // Java NativeMidiMessage class stuff, for passing messages back out to the Java client.
+ jclass mClsNativeMidiMessage;
+ jmethodID mMidNativeMidiMessage_ctor;
+ jfieldID mFid_opcode;
+ jfieldID mFid_buffer;
+ jfieldID mFid_len;
+ jfieldID mFid_timestamp;
+ jfieldID mFid_timeReceived;
+
+ std::mutex lock;
+
+public:
+ // read Thread
+ std::unique_ptr<std::thread> mReadThread;
+ std::atomic<bool> mReading;
+
+ AMidiDevice* nativeDevice;
+ std::atomic<AMidiOutputPort*> midiOutputPort;
+ std::atomic<AMidiInputPort*> midiInputPort;
+
+ TestContext() :
+ mNumSends(0),
+ mNumBytesSent(0),
+ mNumReceives(0),
+ mNumBytesReceived(0),
+ mClsNativeMidiMessage(0),
+ mMidNativeMidiMessage_ctor(0),
+ mFid_opcode(0),
+ mFid_buffer(0),
+ mFid_len(0),
+ mFid_timestamp(0),
+ mFid_timeReceived(0),
+ mReading(false),
+ nativeDevice(nullptr),
+ midiOutputPort(nullptr),
+ midiInputPort(nullptr)
+ {}
+
+ bool initN(JNIEnv* env);
+
+ int getNumSends() { return mNumSends; }
+ void incNumSends() { mNumSends++; }
+
+ int getNumBytesSent() { return mNumBytesSent; }
+ void incNumBytesSent(int numBytes) { mNumBytesSent += numBytes; }
+
+ int getNumReceives() { return mNumReceives; }
+ void incNumReceives() { mNumReceives++; }
+
+ int getNumBytesReceived() { return mNumBytesReceived; }
+ void incNumBytesReceived(int numBytes) { mNumBytesReceived += numBytes; }
+
+ void addSent(SentMessageRecord&& msg) { mSentMsgs.push_back(std::move(msg)); }
+ size_t getNumSentMsgs() { return mSentMsgs.size(); }
+
+ void addReceived(ReceivedMessageRecord&& msg) { mReceivedMsgs.push_back(std::move(msg)); }
+ size_t getNumReceivedMsgs() { return mReceivedMsgs.size(); }
+
+ jobject transferReceiveMsgAt(JNIEnv* env, int index);
+
+ static const int COMPARE_SUCCESS = 0;
+ static const int COMPARE_COUNTMISSMATCH = 1;
+ static const int COMPARE_DATALENMISMATCH = 2;
+ static const int COMPARE_DATAMISMATCH = 3;
+ static const int COMPARE_TIMESTAMPMISMATCH = 4;
+ int compareInsAndOuts();
+
+ static const int CHECKLATENCY_SUCCESS = 0;
+ static const int CHECKLATENCY_COUNTMISSMATCH = 1;
+ static const int CHECKLATENCY_LATENCYEXCEEDED = 2;
+ int checkInOutLatency(long maxLatencyNanos);
+};
+
+//
+// Helpers
+//
+static long System_nanoTime() {
+ // this code is the implementation of System.nanoTime()
+ // from system/code/ojluni/src/main/native/System.
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now.tv_sec * 1000000000LL + now.tv_nsec;
+}
+
+bool TestContext::initN(JNIEnv* env) {
+ static const char* clsSigNativeMidiMessage = "android/nativemidi/cts/NativeMidiMessage";
+
+ jclass cls = env->FindClass(clsSigNativeMidiMessage);
+ if (cls == NULL) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "JNI Error - couldn't find NativeMidiMessage class");
+ return false; // we are doomed, so bail.
+ }
+ mClsNativeMidiMessage = (jclass)env->NewGlobalRef(cls);
+ if (mClsNativeMidiMessage == NULL) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "JNI Error - couldn't allocate NativeMidiMessage");
+ return false; // we are doomed, so bail.
+ }
+
+ mMidNativeMidiMessage_ctor = env->GetMethodID(mClsNativeMidiMessage, "<init>", "()V");
+ mFid_opcode = env->GetFieldID(mClsNativeMidiMessage, "opcode", "I");
+ mFid_buffer = env->GetFieldID(mClsNativeMidiMessage, "buffer", "[B");
+ mFid_len = env->GetFieldID( mClsNativeMidiMessage, "len", "I");
+ mFid_timestamp = env->GetFieldID(mClsNativeMidiMessage, "timestamp", "J");
+ mFid_timeReceived = env->GetFieldID(mClsNativeMidiMessage, "timeReceived", "J");
+ if (mMidNativeMidiMessage_ctor == NULL ||
+ mFid_opcode == NULL ||
+ mFid_buffer == NULL ||
+ mFid_len == NULL ||
+ mFid_timestamp == NULL ||
+ mFid_timeReceived == NULL) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "JNI Error - couldn't load Field IDs");
+ return false; // we are doomed, so bail.
+ }
+
+ return true;
+}
+
+jobject TestContext::transferReceiveMsgAt(JNIEnv* env, int index) {
+ jobject msg = NULL;
+
+ if (index < (int)mReceivedMsgs.size()) {
+ ReceivedMessageRecord receiveRec = std::move(mReceivedMsgs.at(index));
+ msg = env->NewObject(mClsNativeMidiMessage, mMidNativeMidiMessage_ctor);
+
+ env->SetIntField(msg, mFid_opcode, receiveRec.opCode);
+ env->SetIntField(msg, mFid_len, receiveRec.numDataBytes);
+ jobject buffer_array = env->GetObjectField(msg, mFid_buffer);
+ env->SetByteArrayRegion(reinterpret_cast<jbyteArray>(buffer_array), 0,
+ receiveRec.numDataBytes, (jbyte*)receiveRec.dataBuff.get());
+ env->SetLongField(msg, mFid_timestamp, receiveRec.timestamp);
+ env->SetLongField(msg, mFid_timeReceived, receiveRec.timeReceived);
+ }
+
+ return msg;
+}
+
+int TestContext::compareInsAndOuts() {
+ // Number of messages sent/received
+ if (mReceivedMsgs.size() != mSentMsgs.size()) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "---- COMPARE_COUNTMISSMATCH r:%zu s:%zu",
+ mReceivedMsgs.size(), mSentMsgs.size());
+ return COMPARE_COUNTMISSMATCH;
+ }
+
+ // we know that both vectors have the same number of messages from the test above.
+ size_t numMessages = mSentMsgs.size();
+ for (size_t msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ // Data Length?
+ if (mReceivedMsgs[msgIndex].numDataBytes != mSentMsgs[msgIndex].numDataBytes) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "---- COMPARE_DATALENMISMATCH r:%zu s:%zu",
+ mReceivedMsgs[msgIndex].numDataBytes, mSentMsgs[msgIndex].numDataBytes);
+ return COMPARE_DATALENMISMATCH;
+ }
+
+ // Timestamps
+ if (mReceivedMsgs[msgIndex].timestamp != mSentMsgs[msgIndex].timestamp) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "---- COMPARE_TIMESTAMPMISMATCH");
+ return COMPARE_TIMESTAMPMISMATCH;
+ }
+
+ // we know that the data in both messages have the same number of bytes from the test above.
+ int dataLen = mReceivedMsgs[msgIndex].numDataBytes;
+ for (int dataIndex = 0; dataIndex < dataLen; dataIndex++) {
+ // Data Values?
+ if (mReceivedMsgs[msgIndex].dataBuff[dataIndex] !=
+ mSentMsgs[msgIndex].dataBuff[dataIndex]) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "---- COMPARE_DATAMISMATCH r:%d s:%d",
+ (int)mReceivedMsgs[msgIndex].dataBuff[dataIndex],
+ (int)mSentMsgs[msgIndex].dataBuff[dataIndex]);
+ return COMPARE_DATAMISMATCH;
+ }
+ }
+ }
+
+ return COMPARE_SUCCESS;
+}
+
+int TestContext::checkInOutLatency(long maxLatencyNanos) {
+ if (mReceivedMsgs.size() != mSentMsgs.size()) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, " ---- CHECKLATENCY_COUNTMISSMATCH");
+ return CHECKLATENCY_COUNTMISSMATCH;
+ }
+
+ // we know that both vectors have the same number of messages
+ // from the test above.
+ int numMessages = mSentMsgs.size();
+ for (int msgIndex = 0; msgIndex < numMessages; msgIndex++) {
+ long timeDelta = mSentMsgs[msgIndex].timeSent - mReceivedMsgs[msgIndex].timestamp;
+ if (timeDelta > maxLatencyNanos) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ " ---- CHECKLATENCY_LATENCYEXCEEDED %ld", timeDelta);
+ return CHECKLATENCY_LATENCYEXCEEDED;
+ }
+ }
+
+ return CHECKLATENCY_SUCCESS;
+}
+
+JNIEXPORT jlong JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_allocTestContext(
+ JNIEnv* env, jclass) {
+ TestContext* context = new TestContext;
+ if (!context->initN(env)) {
+ delete context;
+ context = NULL;
+ }
+
+ return (jlong)context;
+}
+
+JNIEXPORT void JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_freeTestContext(
+ JNIEnv*, jclass, jlong context) {
+ delete (TestContext*)context;
+}
+
+/*
+ * Receiving API
+ */
+//static void DumpDataMessage(ReceivedMessageRecord* msg) {
+// char midiDumpBuffer[SIZE_DATABUFFER * 4]; // more than enough
+// memset(midiDumpBuffer, 0, sizeof(midiDumpBuffer));
+// int pos = snprintf(midiDumpBuffer, sizeof(midiDumpBuffer),
+// "%" PRIx64 " ", msg->timestamp);
+// for (uint8_t *b = msg->buffer, *e = b + msg->numDataBytes; b < e; ++b) {
+// pos += snprintf(midiDumpBuffer + pos, sizeof(midiDumpBuffer) - pos,
+// "%02x ", *b);
+// }
+// __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "---- DUMP %s", midiDumpBuffer);
+//}
+
+void readThreadRoutine(TestContext* context) {
+ int32_t opCode;
+ uint8_t inDataBuffer[SIZE_DATABUFFER];
+ size_t numDataBytes;
+ int64_t timestamp;
+
+ while (context->mReading) {
+ AMidiOutputPort* outputPort = context->midiOutputPort.load();
+ if (outputPort != nullptr) {
+ ssize_t numMessages =
+ AMidiOutputPort_receive(outputPort, &opCode,
+ inDataBuffer, sizeof(inDataBuffer), &numDataBytes, ×tamp);
+
+ if (numMessages > 0) {
+ context->incNumReceives();
+ context->incNumBytesReceived(numDataBytes);
+ ReceivedMessageRecord receiveRec;
+ receiveRec.timeReceived = System_nanoTime();
+ receiveRec.numDataBytes = numDataBytes;
+ receiveRec.dataBuff.reset(new uint8_t[receiveRec.numDataBytes]);
+ memcpy(receiveRec.dataBuff.get(), inDataBuffer, receiveRec.numDataBytes);
+ receiveRec.opCode = opCode;
+ receiveRec.timestamp = timestamp;
+ context->addReceived(std::move(receiveRec));
+ }
+ }
+ }
+}
+
+static media_status_t commonDeviceOpen(JNIEnv *env, jobject midiDeviceObj, AMidiDevice** device) {
+ media_status_t status = AMidiDevice_fromJava(env, midiDeviceObj, device);
+ if (status == AMEDIA_OK) {
+ // __android_log_print(ANDROID_LOG_INFO, LOG_TAG,
+ // "---- Obtained device token for obj %p: dev %p", midiDeviceObj, device);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "---- Could not obtain device token for obj %p: status:%d", midiDeviceObj, status);
+ }
+
+ return status;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_openNativeMidiDevice(
+ JNIEnv* env, jobject, jlong ctx, jobject deviceObj) {
+ TestContext* context = (TestContext*)ctx;
+ media_status_t status = commonDeviceOpen(env, deviceObj, &context->nativeDevice);
+ return status;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_closeNativeMidiDevice(
+ JNIEnv*, jobject, jlong ctx) {
+ TestContext* context = (TestContext*)ctx;
+ media_status_t status = AMidiDevice_release(context->nativeDevice);
+ return status;
+}
+
+/*
+ * Sending API
+ */
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_startWritingMidi(
+ JNIEnv*, jobject, jlong ctx, jint portNumber) {
+
+ TestContext* context = (TestContext*)ctx;
+
+ AMidiInputPort* inputPort;
+ media_status_t status = AMidiInputPort_open(context->nativeDevice, portNumber, &inputPort);
+ if (status == AMEDIA_OK) {
+ // __android_log_print(ANDROID_LOG_INFO, LOG_TAG,
+ // "---- Opened INPUT port %d: token %p", portNumber, inputPort);
+ context->midiInputPort.store(inputPort);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "---- Could not open INPUT port %p:%d %d",
+ context->nativeDevice, portNumber, status);
+ return status;
+ }
+
+ return AMEDIA_OK;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_stopWritingMidi(
+ JNIEnv*, jobject, jlong ctx) {
+
+ TestContext* context = (TestContext*)ctx;
+
+ AMidiInputPort* inputPort = context->midiInputPort.exchange(nullptr);
+ if (inputPort == nullptr) {
+ return -1;
+ }
+
+ AMidiInputPort_close(inputPort);
+
+ return 0;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_writeMidiWithTimestamp(
+ JNIEnv* env, jobject,
+ jlong ctx, jbyteArray data, jint offset, jint numBytes, jlong timestamp) {
+
+ TestContext* context = (TestContext*)ctx;
+ context->incNumSends();
+ context->incNumBytesSent(numBytes);
+
+ jbyte* bufferPtr = env->GetByteArrayElements(data, NULL);
+ if (bufferPtr == NULL) {
+ return -1;
+ }
+
+ int numWritten = AMidiInputPort_sendWithTimestamp(
+ context->midiInputPort, (uint8_t*)bufferPtr + offset, numBytes, timestamp);
+ if (numWritten > 0) {
+ // Don't save a send record if we didn't send!
+ SentMessageRecord sendRec;
+ sendRec.numDataBytes = numBytes;
+ sendRec.dataBuff.reset(new uint8_t[sendRec.numDataBytes]);
+ memcpy(sendRec.dataBuff.get(), (uint8_t*)bufferPtr + offset, numBytes);
+ sendRec.timestamp = timestamp;
+ sendRec.timeSent = System_nanoTime();
+ context->addSent(std::move(sendRec));
+ }
+
+ env->ReleaseByteArrayElements(data, bufferPtr, JNI_ABORT);
+
+ return numWritten;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_writeMidi(
+ JNIEnv* env, jobject j_object, jlong ctx, jbyteArray data, jint offset, jint numBytes) {
+ return Java_android_nativemidi_cts_NativeMidiEchoTest_writeMidiWithTimestamp(
+ env, j_object, ctx, data, offset, numBytes, 0L);
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_flushSentMessages(
+ JNIEnv*, jobject, jlong ctx) {
+ TestContext* context = (TestContext*)ctx;
+ return AMidiInputPort_sendFlush(context->midiInputPort);
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getNumSends(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->getNumSends();
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getNumBytesSent(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->getNumBytesSent();
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getNumReceives(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->getNumReceives();
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getNumBytesReceived(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->getNumBytesReceived();
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_startReadingMidi(
+ JNIEnv*, jobject, jlong ctx, jint portNumber) {
+
+ // __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "++++ startReadingMidi()");
+ TestContext* context = (TestContext*)ctx;
+
+ AMidiOutputPort* outputPort;
+ media_status_t status = AMidiOutputPort_open(context->nativeDevice, portNumber, &outputPort);
+ if (status == AMEDIA_OK) {
+ context->midiOutputPort.store(outputPort);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+ "---- Could not open OUTPUT port %p : %d %d",
+ context->nativeDevice, portNumber, status);
+ return status;
+ }
+
+ // Start read thread
+ context->mReading = true;
+ context->mReadThread.reset(new std::thread(readThreadRoutine, context));
+ std::this_thread::yield(); // let the read thread startup.
+
+ return status;
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_stopReadingMidi(
+ JNIEnv*, jobject, jlong ctx) {
+
+ // __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "++++ stopReadingMidi()");
+ TestContext* context = (TestContext*)ctx;
+ context->mReading = false;
+
+ context->mReadThread->join();
+
+ AMidiOutputPort* outputPort = context->midiOutputPort.exchange(nullptr);
+ if (outputPort == nullptr) {
+ return -1;
+ }
+
+ AMidiOutputPort_close(outputPort);
+
+ return 0;
+}
+
+/*
+ * Messages
+ */
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getNumReceivedMessages(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->getNumReceivedMsgs();
+}
+
+JNIEXPORT jobject JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_getReceivedMessageAt(
+ JNIEnv* env, jobject, jlong ctx, jint index) {
+ return ((TestContext*)ctx)->transferReceiveMsgAt(env, index);
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_matchNativeMessages(
+ JNIEnv*, jobject, jlong ctx) {
+ return ((TestContext*)ctx)->compareInsAndOuts();
+}
+
+JNIEXPORT jint JNICALL Java_android_nativemidi_cts_NativeMidiEchoTest_checkNativeLatency(
+ JNIEnv*, jobject, jlong ctx, jlong maxLatencyNanos) {
+ return ((TestContext*)ctx)->checkInOutLatency(maxLatencyNanos);
+}
+
+} // extern "C"
diff --git a/tests/tests/nativemidi/res/xml/echo_device_info.xml b/tests/tests/nativemidi/res/xml/echo_device_info.xml
new file mode 100644
index 0000000..9f2ebee
--- /dev/null
+++ b/tests/tests/nativemidi/res/xml/echo_device_info.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<devices>
+ <device manufacturer="AndroidCTS" product="NativeMidiEcho" tags="echo,test">
+ <input-port name="input" />
+ <output-port name="output" />
+ </device>
+</devices>
diff --git a/tests/tests/os/src/android/os/cts/LocaleListTest.java b/tests/tests/os/src/android/os/cts/LocaleListTest.java
index bc30e5c..89780b2 100644
--- a/tests/tests/os/src/android/os/cts/LocaleListTest.java
+++ b/tests/tests/os/src/android/os/cts/LocaleListTest.java
@@ -20,6 +20,8 @@
import android.os.Parcel;
import android.test.AndroidTestCase;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
public class LocaleListTest extends AndroidTestCase {
@@ -247,7 +249,7 @@
assertEquals("ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags());
} finally {
// restore the original values
- LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+ resetDefaultLocaleList(originalLocale, originalLocaleList);
}
}
@@ -281,7 +283,7 @@
assertEquals(locales, LocaleList.getAdjustedDefault());
} finally {
// restore the original values
- LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+ resetDefaultLocaleList(originalLocale, originalLocaleList);
}
}
@@ -297,7 +299,7 @@
assertEquals(locales, LocaleList.getAdjustedDefault());
} finally {
// restore the original values
- LocaleList.setDefault(originalLocaleList, originalLocaleList.indexOf(originalLocale));
+ resetDefaultLocaleList(originalLocale, originalLocaleList);
}
}
@@ -319,6 +321,26 @@
LocaleList.getEmptyLocaleList().describeContents();
}
+ private static void resetDefaultLocaleList(Locale topLocale, LocaleList localeList) {
+ final List<Locale> newLocales = new ArrayList<>();
+
+ if (topLocale != null) {
+ newLocales.add(topLocale);
+ }
+
+ if (localeList != null) {
+ for (int index = 0; index < localeList.size(); index++) {
+ final Locale locale = localeList.get(index);
+ if (topLocale != null && !topLocale.equals(locale)) {
+ newLocales.add(locale);
+ }
+ }
+ }
+
+ final LocaleList result = new LocaleList(newLocales.toArray(new Locale[newLocales.size()]));
+ LocaleList.setDefault(result);
+ }
+
private static LocaleList cloneViaParcel(final LocaleList original) {
Parcel parcel = null;
try {
diff --git a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
index da72966..ccc1f1a 100644
--- a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
+++ b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
@@ -29,6 +29,8 @@
public class SecurityPatchTest extends InstrumentationTestCase {
private static final String TAG = SecurityPatchTest.class.getSimpleName();
+ private static final String MISSING_BOOT_SECURITY_PATCH_LEVEL =
+ "ro.boot.security_patch should be defined in the device specific BoardConfig.mk on the BOARD_KERNEL_COMMANDLINE";
private static final String SECURITY_PATCH_ERROR =
"security_patch should be in the format \"YYYY-MM-DD\". Found \"%s\"";
private static final String SECURITY_PATCH_DATE_ERROR =
@@ -39,12 +41,14 @@
private boolean mSkipTests = false;
private String mVendorSecurityPatch;
private String mBuildSecurityPatch;
+ private String mBootSecurityPatch;
@Override
protected void setUp() {
mSkipTests = (ApiLevelUtil.isBefore(Build.VERSION_CODES.M));
mVendorSecurityPatch = SystemProperties.get("ro.vendor.build.security_patch", "");
mBuildSecurityPatch = Build.VERSION.SECURITY_PATCH;
+ mBootSecurityPatch = SystemProperties.get("ro.boot.security_patch", "");
}
/** Security patch string must exist in M or higher **/
@@ -57,6 +61,7 @@
assertTrue(error, !mBuildSecurityPatch.isEmpty());
}
+ /** Vendor security patch string must exist in P or higher **/
public void testVendorSecurityPatchFound() {
if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) {
Log.w(TAG, "Skipping P+ Test");
@@ -65,6 +70,15 @@
assertTrue(!mVendorSecurityPatch.isEmpty());
}
+ /** Boot security patch string must exist in P or higher **/
+ public void testBootSecurityPatchFound() {
+ if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) {
+ Log.w(TAG, "Skipping P+ Test");
+ return;
+ }
+ assertTrue(MISSING_BOOT_SECURITY_PATCH_LEVEL, !mBootSecurityPatch.isEmpty());
+ }
+
public void testSecurityPatchesFormat() {
if (mSkipTests) {
Log.w(TAG, "Skipping M+ Test.");
@@ -79,6 +93,9 @@
}
error = String.format(SECURITY_PATCH_ERROR, mVendorSecurityPatch);
testSecurityPatchFormat(mVendorSecurityPatch, error);
+
+ error = String.format(SECURITY_PATCH_ERROR, mBootSecurityPatch);
+ testSecurityPatchFormat(mBootSecurityPatch, error);
}
/** Security patch should be of the form YYYY-MM-DD in M or higher */
@@ -117,7 +134,14 @@
SECURITY_PATCH_MONTH,
mVendorSecurityPatch);
testSecurityPatchDate(mVendorSecurityPatch, error);
+
+ error = String.format(SECURITY_PATCH_DATE_ERROR,
+ SECURITY_PATCH_YEAR,
+ SECURITY_PATCH_MONTH,
+ mBootSecurityPatch);
+ testSecurityPatchDate(mBootSecurityPatch, error);
}
+
/** Security patch should no older than the month this test was updated in M or higher **/
private void testSecurityPatchDate(String patch, String error) {
int declaredYear = 0;
diff --git a/tests/tests/os/src/android/os/cts/VibrationEffectTest.java b/tests/tests/os/src/android/os/cts/VibrationEffectTest.java
index 50237f0..0f2a1c2 100644
--- a/tests/tests/os/src/android/os/cts/VibrationEffectTest.java
+++ b/tests/tests/os/src/android/os/cts/VibrationEffectTest.java
@@ -17,6 +17,7 @@
package android.os.cts;
import android.content.Context;
+import android.hardware.vibrator.V1_0.EffectStrength;
import android.media.AudioAttributes;
import android.os.Parcel;
import android.os.VibrationEffect;
@@ -31,8 +32,10 @@
import java.util.Arrays;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@SmallTest
@@ -51,13 +54,22 @@
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
private static final VibrationEffect TEST_WAVEFORM_NO_AMPLITUDES =
VibrationEffect.createWaveform(TEST_TIMINGS, -1);
+ private static final VibrationEffect TEST_PREBAKED =
+ VibrationEffect.get(VibrationEffect.EFFECT_CLICK, true);
@Test
public void testCreateOneShot() {
- VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
- VibrationEffect.createOneShot(1, 1);
- VibrationEffect.createOneShot(1000, 255);
+ VibrationEffect e = VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
+ assertEquals(100, e.getDuration());
+ assertEquals(VibrationEffect.DEFAULT_AMPLITUDE,
+ ((VibrationEffect.OneShot)e).getAmplitude());
+ e = VibrationEffect.createOneShot(1, 1);
+ assertEquals(1, e.getDuration());
+ assertEquals(1, ((VibrationEffect.OneShot)e).getAmplitude());
+ e = VibrationEffect.createOneShot(1000, 255);
+ assertEquals(1000, e.getDuration());
+ assertEquals(255, ((VibrationEffect.OneShot)e).getAmplitude());
}
@Test
@@ -76,6 +88,11 @@
} catch (IllegalArgumentException expected) { }
try {
+ VibrationEffect.createOneShot(TEST_TIMING, 0);
+ fail("Invalid amplitude, should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) { }
+
+ try {
VibrationEffect.createOneShot(TEST_TIMING, 256);
fail("Invalid amplitude, should throw IllegalArgumentException");
} catch (IllegalArgumentException expected) { }
@@ -113,10 +130,42 @@
}
@Test
+ public void testCreatePrebaked() {
+ int[] ids = { VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_DOUBLE_CLICK,
+ VibrationEffect.EFFECT_TICK, VibrationEffect.EFFECT_THUD,
+ VibrationEffect.EFFECT_POP, VibrationEffect.EFFECT_HEAVY_CLICK };
+ boolean[] fallbacks = { false, true };
+ for (int id : ids) {
+ for (boolean fallback : fallbacks) {
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)
+ VibrationEffect.get(id, fallback);
+ assertEquals(id, effect.getId());
+ assertEquals(fallback, effect.shouldFallback());
+ assertEquals(-1, effect.getDuration());
+ }
+ }
+ }
+
+ @Test
public void testCreateWaveform() {
- VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
- VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, 0);
- VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, TEST_AMPLITUDES.length - 1);
+ VibrationEffect.Waveform effect = (VibrationEffect.Waveform)
+ VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
+ assertArrayEquals(TEST_TIMINGS, effect.getTimings());
+ assertArrayEquals(TEST_AMPLITUDES, effect.getAmplitudes());
+ assertEquals(-1, effect.getRepeatIndex());
+ assertEquals(400, effect.getDuration());
+ effect = (VibrationEffect.Waveform)
+ VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, 0);
+ assertArrayEquals(TEST_TIMINGS, effect.getTimings());
+ assertArrayEquals(TEST_AMPLITUDES, effect.getAmplitudes());
+ assertEquals(0, effect.getRepeatIndex());
+ assertEquals(Long.MAX_VALUE, effect.getDuration());
+ effect = (VibrationEffect.Waveform)VibrationEffect.createWaveform(TEST_TIMINGS,
+ TEST_AMPLITUDES, TEST_AMPLITUDES.length - 1);
+ assertArrayEquals(TEST_TIMINGS, effect.getTimings());
+ assertArrayEquals(TEST_AMPLITUDES, effect.getAmplitudes());
+ assertEquals(TEST_AMPLITUDES.length - 1, effect.getRepeatIndex());
+ assertEquals(Long.MAX_VALUE, effect.getDuration());
}
@Test
@@ -278,17 +327,72 @@
}
@Test
- public void testParceling() {
+ public void testParcelingOneShot() {
Parcel p = Parcel.obtain();
TEST_ONE_SHOT.writeToParcel(p, 0);
p.setDataPosition(0);
VibrationEffect parceledEffect = VibrationEffect.CREATOR.createFromParcel(p);
assertEquals(TEST_ONE_SHOT, parceledEffect);
+ }
- p.setDataPosition(0);
+ @Test
+ public void testParcelingWaveForm() {
+ Parcel p = Parcel.obtain();
TEST_WAVEFORM.writeToParcel(p, 0);
p.setDataPosition(0);
- parceledEffect = VibrationEffect.CREATOR.createFromParcel(p);
+ VibrationEffect parceledEffect = VibrationEffect.CREATOR.createFromParcel(p);
assertEquals(TEST_WAVEFORM, parceledEffect);
}
+
+ @Test
+ public void testParcelingPrebaked() {
+ Parcel p = Parcel.obtain();
+ TEST_PREBAKED.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ VibrationEffect parceledEffect = VibrationEffect.CREATOR.createFromParcel(p);
+ assertEquals(TEST_PREBAKED, parceledEffect);
+ }
+
+ @Test
+ public void testDescribeContents() {
+ TEST_ONE_SHOT.describeContents();
+ TEST_WAVEFORM.describeContents();
+ TEST_WAVEFORM_NO_AMPLITUDES.describeContents();
+ TEST_PREBAKED.describeContents();
+ }
+
+ @Test
+ public void testSetStrength() {
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)VibrationEffect.get(
+ VibrationEffect.EFFECT_CLICK, true);
+ int[] strengths = { EffectStrength.LIGHT, EffectStrength.MEDIUM, EffectStrength.STRONG};
+ for (int strength : strengths) {
+ effect.setEffectStrength(strength);
+ assertEquals(strength, effect.getEffectStrength());
+ }
+ }
+
+ @Test
+ public void testSetStrengthInvalid() {
+ VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked)VibrationEffect.get(
+ VibrationEffect.EFFECT_CLICK, true);
+ try {
+ effect.setEffectStrength(239017);
+ fail("Illegal strength, should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ @Test
+ public void testPrebakedEquals() {
+ VibrationEffect otherEffect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK, true);
+ assertEquals(TEST_PREBAKED, otherEffect);
+ assertEquals(TEST_PREBAKED.hashCode(), otherEffect.hashCode());
+ }
+
+ @Test
+ public void testToString() {
+ TEST_ONE_SHOT.toString();
+ TEST_WAVEFORM.toString();
+ TEST_PREBAKED.toString();
+ }
}
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index 1a4eec6..e924392 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -27,8 +27,6 @@
# Include both the 32 and 64 bit versions
LOCAL_MULTILIB := both
-LOCAL_JAVA_LIBRARIES := telephony-common
-
LOCAL_STATIC_JAVA_LIBRARIES := \
ctstestrunner \
guava \
@@ -41,9 +39,8 @@
LOCAL_PACKAGE_NAME := CtsPermissionTestCases
-# uncomment when b/13249777 is fixed
-#LOCAL_SDK_VERSION := current
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
+
LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
LOCAL_JAVA_LIBRARIES += android.test.base.stubs
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index c516a60..79deeba 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -43,6 +43,5 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.permission.cts" />
<option name="runtime-hint" value="13m" />
- <option name="hidden-api-checks" value="false" />
</test>
</configuration>
diff --git a/tests/tests/permission/jni/Android.mk b/tests/tests/permission/jni/Android.mk
index 96b7506..b0d16a8 100644
--- a/tests/tests/permission/jni/Android.mk
+++ b/tests/tests/permission/jni/Android.mk
@@ -17,6 +17,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libctspermission_jni
+LOCAL_SDK_VERSION := current
# Don't include this package in any configuration by default.
LOCAL_MODULE_TAGS := optional
@@ -29,7 +30,7 @@
LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
LOCAL_CPPFLAGS := -std=gnu++11
-LOCAL_CXX_STL := libc++_static
+LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
diff --git a/tests/tests/permission/src/android/permission/cts/DevicePowerPermissionTest.java b/tests/tests/permission/src/android/permission/cts/DevicePowerPermissionTest.java
deleted file mode 100644
index 006fb6d..0000000
--- a/tests/tests/permission/src/android/permission/cts/DevicePowerPermissionTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.permission.cts;
-
-import android.content.Context;
-import android.os.PowerManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-/**
- * Verify that various PowerManagement functionality requires Permission.
- */
-public class DevicePowerPermissionTest extends AndroidTestCase {
- PowerManager mPowerManager;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- }
-
- /**
- * Verify that going to sleep requires Permission.
- * <p>Requires Permission:
- * {@link android.Manifest.permission#DEVICE_POWER}.
- */
- @LargeTest
- public void testGoToSleep() {
- try {
- mPowerManager.goToSleep(0);
- fail("Was able to call PowerManager.goToSleep without DEVICE_POWER Permission.");
- } catch (SecurityException e) {
- // expected
- }
- }
-}
diff --git a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
index 909ac35..93f53cb 100644
--- a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
@@ -21,12 +21,17 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.Uri;
import android.provider.CallLog;
import android.provider.Contacts;
+import android.provider.ContactsContract;
import android.provider.Settings;
+import android.provider.Telephony;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -35,18 +40,36 @@
*/
@MediumTest
public class ProviderPermissionTest extends AndroidTestCase {
+
+ private static final String TAG = ProviderPermissionTest.class.getSimpleName();
+
+ private static final List<Uri> CONTACT_URIS = new ArrayList<Uri>() {{
+ add(Contacts.People.CONTENT_URI); // Deprecated.
+ add(ContactsContract.Contacts.CONTENT_FILTER_URI);
+ add(ContactsContract.Contacts.CONTENT_GROUP_URI);
+ add(ContactsContract.Contacts.CONTENT_LOOKUP_URI);
+ add(ContactsContract.CommonDataKinds.Email.CONTENT_URI);
+ add(ContactsContract.CommonDataKinds.Email.CONTENT_FILTER_URI);
+ add(ContactsContract.Directory.CONTENT_URI);
+ add(ContactsContract.Directory.ENTERPRISE_CONTENT_URI);
+ add(ContactsContract.Profile.CONTENT_URI);
+ }};
+
/**
- * Verify that read and write to contact requires permissions.
+ * Verify that reading contacts requires permissions.
* <p>Tests Permission:
* {@link android.Manifest.permission#READ_CONTACTS}
*/
public void testReadContacts() {
- assertReadingContentUriRequiresPermission(Contacts.People.CONTENT_URI,
- android.Manifest.permission.READ_CONTACTS);
+ for (Uri uri : CONTACT_URIS) {
+ Log.d(TAG, "Checking contacts URI " + uri);
+ assertReadingContentUriRequiresPermission(uri,
+ android.Manifest.permission.READ_CONTACTS);
+ }
}
/**
- * Verify that write to contact requires permissions.
+ * Verify that writing contacts requires permissions.
* <p>Tests Permission:
* {@link android.Manifest.permission#WRITE_CONTACTS}
*/
@@ -76,6 +99,23 @@
}
/**
+ * Verify that reading already received SMS messages requires permissions.
+ * <p>Tests Permission:
+ * {@link android.Manifest.permission#READ_SMS}
+ *
+ * <p>Note: The WRITE_SMS permission has been removed.
+ */
+ public void testReadSms() {
+ if (!mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+
+ assertReadingContentUriRequiresPermission(Telephony.Sms.CONTENT_URI,
+ android.Manifest.permission.READ_SMS);
+ }
+
+ /**
* Verify that write to settings requires permissions.
* <p>Tests Permission:
* {@link android.Manifest.permission#WRITE_SETTINGS}
diff --git a/tests/tests/permission/src/android/permission/cts/SmsManagerPermissionTest.java b/tests/tests/permission/src/android/permission/cts/SmsManagerPermissionTest.java
new file mode 100644
index 0000000..ab099ee
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/SmsManagerPermissionTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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.permission.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.SmsManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * Test that sending SMS and MMS messages requires permissions.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SmsManagerPermissionTest {
+
+ private static final String SOURCE_ADDRESS = "+15550000000";
+ private static final String DESTINATION_ADDRESS = "+15550000001";
+
+ private boolean mHasTelephony;
+ private SmsManager mSmsManager;
+ private Context mContext;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mHasTelephony = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY);
+ assumeTrue(mHasTelephony); // Don't run these tests if FEATURE_TELEPHONY is not available.
+
+ mSmsManager = SmsManager.getDefault();
+ assertNotNull(mSmsManager);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSendTextMessage() {
+ mSmsManager.sendTextMessage(
+ DESTINATION_ADDRESS, SOURCE_ADDRESS, "Message text", null, null);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSendTextMessageWithoutPersisting() {
+ mSmsManager.sendTextMessageWithoutPersisting(
+ DESTINATION_ADDRESS, SOURCE_ADDRESS, "Message text", null, null);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSendMultipartTextMessage() {
+ ArrayList<String> messageParts = new ArrayList<>();
+ messageParts.add("Message text");
+ mSmsManager.sendMultipartTextMessage(
+ DESTINATION_ADDRESS, SOURCE_ADDRESS, messageParts, null, null);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSendDataMessage() {
+ mSmsManager.sendDataMessage(
+ DESTINATION_ADDRESS, SOURCE_ADDRESS, (short) 1, new byte[]{0, 0, 0}, null, null);
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSendMultimediaMessage() {
+ // Ideally we would provide an Uri to an existing resource, to make sure the
+ // SecurityException is not due to the invalid Uri.
+ Uri uri = Uri.parse("android.resource://android.permission.cts/some-image.png");
+ mSmsManager.sendMultimediaMessage(mContext, uri, "", null, null);
+ }
+}
diff --git a/tests/tests/permission/src/android/permission/cts/SuspendAppsPermissionTest.java b/tests/tests/permission/src/android/permission/cts/SuspendAppsPermissionTest.java
deleted file mode 100644
index aa7452e..0000000
--- a/tests/tests/permission/src/android/permission/cts/SuspendAppsPermissionTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2018 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.permission.cts;
-
-import static android.Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
-import static android.Manifest.permission.SUSPEND_APPS;
-import static android.content.Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class SuspendAppsPermissionTest {
-
- private PackageManager mPackageManager;
-
- @Before
- public void setUp() {
- mPackageManager = InstrumentationRegistry.getTargetContext().getPackageManager();
- }
-
- @Test
- public void testNumberOfAppsWithPermission() {
- final List<PackageInfo> packagesWithPerm = mPackageManager.getPackagesHoldingPermissions(
- new String[]{SUSPEND_APPS}, 0);
- assertTrue("At most one app can hold the permission " + SUSPEND_APPS + ", but found more: "
- + packagesWithPerm, packagesWithPerm.size() <= 1);
- }
-
- @Ignore // TODO b/75974141: Remove once com.google.android.apps.wellbeing handles the action
- @Test
- public void testShowSuspendedAppDetailsDeclared() {
- final List<PackageInfo> packagesWithPerm = mPackageManager.getPackagesHoldingPermissions(
- new String[]{SUSPEND_APPS}, 0);
- final Intent showDetailsIntent = new Intent(ACTION_SHOW_SUSPENDED_APP_DETAILS);
- boolean success = true;
- StringBuilder errorString = new StringBuilder();
- for (PackageInfo packageInfo : packagesWithPerm) {
- showDetailsIntent.setPackage(packageInfo.packageName);
- final ResolveInfo resolveInfo = mPackageManager.resolveActivity(showDetailsIntent, 0);
- if (resolveInfo == null || resolveInfo.activityInfo == null) {
- errorString.append("No activity found for " + ACTION_SHOW_SUSPENDED_APP_DETAILS
- + " inside package " + packageInfo.packageName);
- success = false;
- }
- else if (!SEND_SHOW_SUSPENDED_APP_DETAILS.equals(resolveInfo.activityInfo.permission)) {
- errorString.append("Activity handling " + ACTION_SHOW_SUSPENDED_APP_DETAILS
- + " not protected with permission " + SEND_SHOW_SUSPENDED_APP_DETAILS);
- success = false;
- }
- }
- if (!success) {
- fail(errorString.toString());
- }
- }
-}
diff --git a/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java b/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
index d117e19..dcc9cdb 100644
--- a/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/TelephonyManagerPermissionTest.java
@@ -275,48 +275,6 @@
}
}
- /**
- * Verify that TelephonyManager.setAllowedCarriers requires Permission.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE}.
- */
- @Test
- public void testSetAllowedCarriers() {
- if (!mHasTelephony
- || !getContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)) {
- return;
- }
- try {
- mTelephonyManager.setAllowedCarriers(0, Collections.emptyList());
- fail("Able to set allowed carriers");
- } catch (SecurityException e) {
- // expected
- }
- }
-
- /**
- * Verify that TelephonyManager.getAllowedCarriers requires Permission.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}.
- */
- @Test
- public void testGetAllowedCarriers() {
- if (!mHasTelephony
- || !getContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)) {
- return;
- }
- try {
- mTelephonyManager.getAllowedCarriers(0);
- fail("Able to get allowed carriers");
- } catch (SecurityException e) {
- // expected
- }
- }
-
private static Context getContext() {
return InstrumentationRegistry.getContext();
}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowLandscapeTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowLandscapeTest.java
index e0f387b..8e042d7 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowLandscapeTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowLandscapeTest.java
@@ -101,14 +101,6 @@
}
/**
- * Landscape setup of {@link #startWithFragmentAndInitTitleMultiWindowInner}.
- */
- @Test
- public void startWithFragmentAndInitTitleMultiWindowLandscapeTest() {
- startWithFragmentAndInitTitleMultiWindowInner();
- }
-
- /**
* Landscape setup of {@link #startWithFragmentNoHeadersInner}.
*/
@Test
@@ -125,14 +117,6 @@
}
/**
- * Landscape setup of {@link #startWithFragmentNoHeadersMultiWindowTest}.
- */
- @Test
- public void startWithFragmentNoHeadersMultiWindowLandscapeTest() {
- startWithFragmentNoHeadersMultiWindowTest();
- }
-
- /**
* Landscape setup of {@link #listDialogTest}.
*/
@Test
@@ -156,38 +140,6 @@
recreateInnerFragmentTest();
}
- /**
- * Landscape setup of {@link #multiWindowInOutTest}.
- */
- @Test
- public void multiWindowInOutLandscapeTest() {
- multiWindowInOutTest();
- }
-
- /**
- * Landscape setup of {@link #multiWindowInnerFragmentInOutTest}.
- */
- @Test
- public void multiWindowInnerFragmentInOutLandscapeTest() {
- multiWindowInnerFragmentInOutTest();
- }
-
- /**
- * Landscape setup of {@link #multiWindowInitialHeaderOnBackTest}.
- */
- @Test
- public void multiWindowInitialHeaderOnBackLandscapeTest() {
- multiWindowInitialHeaderOnBackTest();
- }
-
- /**
- * Landscape setup of {@link #multiWindowHistoryPreserveTest}.
- */
- @Test
- public void multiWindowHistoryPreserveLandscapeTest() {
- multiWindowHistoryPreserveTest();
- }
-
@Override
protected PreferenceWithHeaders launchActivity(Intent intent) {
if (intent != null) {
@@ -200,9 +152,7 @@
@Override
protected void runOnUiThread(final Runnable runnable) {
try {
- mActivityRule.runOnUiThread(() -> {
- runnable.run();
- });
+ mActivityRule.runOnUiThread(runnable);
} catch (Throwable ex) {
throw new RuntimeException("Failure on the UI thread", ex);
}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowPortraitTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowPortraitTest.java
index 1caed6f..ab3922e 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowPortraitTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowPortraitTest.java
@@ -101,14 +101,6 @@
}
/**
- * Portrait setup of {@link #startWithFragmentAndInitTitleMultiWindowInner}.
- */
- @Test
- public void startWithFragmentAndInitTitleMultiWindowPortraitTest() {
- startWithFragmentAndInitTitleMultiWindowInner();
- }
-
- /**
* Portrait setup of {@link #startWithFragmentNoHeadersInner}.
*/
@Test
@@ -125,14 +117,6 @@
}
/**
- * Portrait setup of {@link #startWithFragmentNoHeadersMultiWindowTest}.
- */
- @Test
- public void startWithFragmentNoHeadersMultiWindowPortraitTest() {
- startWithFragmentNoHeadersMultiWindowTest();
- }
-
- /**
* Portrait setup of {@link #listDialogTest}.
*/
@Test
@@ -156,38 +140,6 @@
recreateInnerFragmentTest();
}
- /**
- * Portrait setup of {@link #multiWindowInOutTest}.
- */
- @Test
- public void multiWindowInOutPortraitTest() {
- multiWindowInOutTest();
- }
-
- /**
- * Portrait setup of {@link #multiWindowInnerFragmentInOutTest}.
- */
- @Test
- public void multiWindowInnerFragmentInOutPortraitTest() {
- multiWindowInnerFragmentInOutTest();
- }
-
- /**
- * Portrait setup of {@link #multiWindowInitialHeaderOnBackTest}.
- */
- @Test
- public void multiWindowInitialHeaderOnBackPortraitTest() {
- multiWindowInitialHeaderOnBackTest();
- }
-
- /**
- * Portrait setup of {@link #multiWindowHistoryPreserveTest}.
- */
- @Test
- public void multiWindowHistoryPreservePortraitTest() {
- multiWindowHistoryPreserveTest();
- }
-
@Override
protected PreferenceWithHeaders launchActivity(Intent intent) {
if (intent != null) {
@@ -200,9 +152,7 @@
@Override
protected void runOnUiThread(final Runnable runnable) {
try {
- mActivityRule.runOnUiThread(() -> {
- runnable.run();
- });
+ mActivityRule.runOnUiThread(runnable);
} catch (Throwable ex) {
throw new RuntimeException("Failure on the UI thread", ex);
}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
index 253f8f6..28071ac 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
@@ -27,7 +27,6 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.SystemClock;
-import android.preference2.cts.R;
import android.util.Log;
import com.android.compatibility.common.util.BitmapUtils;
@@ -325,36 +324,6 @@
}
/**
- * For: Large screen (multi-pane).
- * Scenario: Tests that initial title is displayed or hidden properly when transitioning in and
- * out of the multi-window mode.
- */
- void startWithFragmentAndInitTitleMultiWindowInner() {
- launchActivityWithExtras(PreferenceWithHeaders.PrefsTwoFragment.class,
- false /* noHeaders */, INITIAL_TITLE_RES_ID);
- if (!shouldRunLargeDeviceTest()) {
- return;
- }
-
- assertInitialStateForFragment();
- String testTitle = mActivity.getResources().getString(INITIAL_TITLE_RES_ID);
-
- // Title should not be shown (we are in multi-pane).
- assertFalse(mTestUtils.isTextShown(testTitle));
-
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.getMultiWindowFocus(mActivity);
-
- // Title should be shown (we are in single-pane).
- assertTextShown(testTitle);
-
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Title should not be shown (we are back in multi-pane).
- assertTextHidden(testTitle);
- }
-
- /**
* For: Any screen (single or multi-pane).
* Scenario: Tests that EXTRA_NO_HEADERS intent arg that prevents showing headers in multi-pane
* is applied correctly.
@@ -390,34 +359,6 @@
/**
* For: Any screen (single or multi-pane).
- * Scenario: Tests that EXTRA_NO_HEADERS intent arg that prevents showing headers survives
- * correctly multi-window changes. Tested via screenshots.
- */
- void startWithFragmentNoHeadersMultiWindowTest() {
- launchActivityWithExtras(PreferenceWithHeaders.PrefsTwoFragment.class,
- true /* noHeaders */, -1 /* initialTitle */);
-
- assertInitialStateForFragment();
-
- // Workaround for some focus bug in the framework
- mTestUtils.tapOnViewWithText(PREFS2_PANEL_TITLE);
-
- // Take screenshot
- Bitmap before = mTestUtils.takeScreenshot();
-
- // Enter and leave multi-window.
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.leaveMultiWindow(mActivity);
-
- assertInitialStateForFragment();
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
- /**
- * For: Any screen (single or multi-pane).
* Scenario: Tests that list preference opens correctly and that back press correctly closes it.
*/
void listDialogTest() {
@@ -515,163 +456,6 @@
assertScreenshotsAreEqual(before, after);
}
- /**
- * For: Any screen (single or multi-pane).
- * Scenario: Tests that the PreferenceActivity properly restores its state after going to
- * multi-window and back. Test done via screenshots.
- */
- void multiWindowInOutTest() {
- launchActivity();
-
- assertInitialState();
- // Tap on Prefs2 header.
- tapOnPrefs2Header();
-
- assertPanelPrefs2Shown();
-
- // Take screenshot
- Bitmap before = mTestUtils.takeScreenshot();
-
- // Enter and leave multi-window.
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.leaveMultiWindow(mActivity);
-
- assertPanelPrefs2Shown();
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
- /**
- * For: Any screen (single or multi-pane).
- * Scenario: Tests that the PreferenceActivity properly restores its state after going to
- * multi-window and back while an inner fragment is shown. Test done via screenshots.
- */
- void multiWindowInnerFragmentInOutTest() {
- launchActivity();
-
- assertInitialState();
- if (!mIsMultiPane) {
- tapOnPrefs1Header();
- }
-
- // Go to preferences inner fragment.
- mTestUtils.tapOnViewWithText(INNER_FRAGMENT_PREF_BUTTON);
-
- // We don't need to check that correct panel is displayed that is already covered by
- // smallScreenGoToFragmentInner and largeScreenGoToFragmentInner
-
- // Take screenshot
- Bitmap before = mTestUtils.takeScreenshot();
-
- // Enter and leave multi-window.
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
- /**
- * For: Large screen (single or multi-pane).
- * Scenario: Goes to single-pane by entering multi-window and tests that back press ends up with
- * a list of headers and nothing else. Then leaves multi-window back to single-pane and tests if
- * the proper default header was opened (screenshot test).
- */
- void multiWindowInitialHeaderOnBackTest() {
- launchActivity();
- if (!shouldRunLargeDeviceTest()) {
- return;
- }
-
- assertInitialState();
-
- Bitmap before = mTestUtils.takeScreenshot();
-
- // Enter multi-window.
- mTestUtils.enterMultiWindow(mActivity);
-
- // Get window focus (otherwise back press would close multi-window instead of firing to the
- // Activity.
- mTestUtils.getMultiWindowFocus(mActivity);
-
- pressBack();
-
- // Only headers should be shown (also checks that we have correct focus).
- assertHeadersShown();
- assertPanelPrefs1Hidden();
- assertPanelPrefs2Hidden();
-
- // Leave multi-window
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Headers and Prefs1 should be shown.
- assertHeadersShown();
- assertPanelPrefs1Shown();
- assertPanelPrefs2Hidden();
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
- /**
- * For: Large screen (multi-pane).
- * Scenario: Tests that history is preserved correctly while transitioning to multi-window.
- * Navigates to Prefs2 pane and then goes to single-pane mode via multi-window. Test that back
- * press navigates to the headers list. Then tests that restoring multi-pane by leaving
- * multi-window opens the same screen with which was the activity started before (screenshot
- * test).
- */
- void multiWindowHistoryPreserveTest() {
- launchActivity();
- if (!shouldRunLargeDeviceTest()) {
- return;
- }
-
- assertInitialState();
- Bitmap before = mTestUtils.takeScreenshot();
-
- tapOnPrefs2Header();
-
- // Enter multi-window.
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.getMultiWindowFocus(mActivity);
-
- // Only Prefs2 should be shown (also checks that we have correct focus).
- assertHeadersHidden();
- assertPanelPrefs1Hidden();
- assertPanelPrefs2Shown();
-
- pressBack();
-
- // Only headers should be shown.
- assertHeadersShown();
- assertPanelPrefs1Hidden();
- assertPanelPrefs2Hidden();
-
- tapOnPrefs1Header();
-
- // Only Prefs1 should be shown.
- assertHeadersHidden();
- assertPanelPrefs1Shown();
- assertPanelPrefs2Hidden();
-
- // Leave multi-window
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Headers and Prefs1 should be shown.
- assertHeadersShown();
- assertPanelPrefs1Shown();
- assertPanelPrefs2Hidden();
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
private void assertScreenshotsAreEqual(Bitmap before, Bitmap after) {
assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after));
}
@@ -690,7 +474,6 @@
assertPanelPrefs1Hidden();
assertPanelPrefs2Hidden();
}
-
assertHeadersAreLoaded();
}
@@ -708,8 +491,6 @@
assertPanelPrefs1Hidden();
assertPanelPrefs2Shown();
}
-
-
}
public boolean shouldRunLargeDeviceTest() {
@@ -739,12 +520,10 @@
}
private void assertHeadersAreLoaded() {
- runOnUiThread(() -> {
- assertEquals(EXPECTED_HEADERS_COUNT,
- mActivity.loadedHeaders == null
- ? 0
- : mActivity.loadedHeaders.size());
- });
+ runOnUiThread(() -> assertEquals(EXPECTED_HEADERS_COUNT,
+ mActivity.loadedHeaders == null
+ ? 0
+ : mActivity.loadedHeaders.size()));
}
private void assertHeadersShown() {
@@ -822,9 +601,7 @@
private void launchActivity() {
mActivity = launchActivity(null);
mTestUtils.device.waitForIdle();
- runOnUiThread(() -> {
- mIsMultiPane = mActivity.isMultiPane();
- });
+ runOnUiThread(() -> mIsMultiPane = mActivity.isMultiPane());
}
private void launchActivityWithExtras(Class extraFragment, boolean noHeaders,
@@ -843,9 +620,7 @@
mActivity = launchActivity(intent);
mTestUtils.device.waitForIdle();
- runOnUiThread(() -> {
- mIsMultiPane = mActivity.isMultiPane();
- });
+ runOnUiThread(() -> mIsMultiPane = mActivity.isMultiPane());
}
protected abstract PreferenceWithHeaders launchActivity(Intent intent);
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityLegacyFlowTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityLegacyFlowTest.java
index b3d8b8d..46863cb 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityLegacyFlowTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityLegacyFlowTest.java
@@ -84,44 +84,6 @@
assertScreenshotsAreEqual(before, after);
}
- /**
- * Scenario: Tests that the activity still shows the preference screen even after multi-window
- * is entered.
- */
- @Test
- public void legacyActivityMultiWindowTest() {
- waitForIdle();
-
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.getMultiWindowFocus(mActivity);
-
- // Prefs list should be shown.
- assertTextShown(LEGACY_SCREEN_TEXT);
-
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Prefs list should be shown.
- assertTextShown(LEGACY_SCREEN_TEXT);
- }
-
- /**
- * Scenario: Tests that the activity correctly restores its state after multi-window changes
- * in legacy mode.
- */
- @Test
- public void legacyActivityMultiWindowToggleTest() {
- waitForIdle();
-
- Bitmap before = mTestUtils.takeScreenshot();
-
- mTestUtils.enterMultiWindow(mActivity);
- mTestUtils.leaveMultiWindow(mActivity);
-
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
- }
-
private void recreate() {
runOnUiThread(() -> mActivity.recreate());
SystemClock.sleep(1000);
@@ -130,9 +92,7 @@
private void runOnUiThread(final Runnable runnable) {
try {
- mActivityRule.runOnUiThread(() -> {
- runnable.run();
- });
+ mActivityRule.runOnUiThread(() -> runnable.run());
} catch (Throwable ex) {
throw new RuntimeException("Failure on the UI thread", ex);
}
diff --git a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
index e00e658..568b6f9 100644
--- a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
+++ b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
@@ -16,26 +16,17 @@
package android.preference2.cts;
-import android.app.Activity;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.app.UiModeManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
-import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiScrollable;
-import android.support.test.uiautomator.UiSelector;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
/**
* Collection of helper utils for testing preferences.
@@ -43,19 +34,24 @@
public class TestUtils {
final UiDevice device;
+
+ private final Context mContext;
private final Instrumentation mInstrumentation;
+ private final String mPackageName;
private final UiAutomation mAutomation;
private int mStatusBarHeight = -1;
private int mNavigationBarHeight = -1;
TestUtils() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mContext = mInstrumentation.getTargetContext();
+ mPackageName = mContext.getPackageName();
device = UiDevice.getInstance(mInstrumentation);
mAutomation = mInstrumentation.getUiAutomation();
}
Bitmap takeScreenshot() {
- // Only take screenshot once the screen is stable enough.
+ // Only take a screenshot once the screen is stable enough.
device.waitForIdle();
Bitmap bt = mAutomation.takeScreenshot();
@@ -66,8 +62,8 @@
// Crop-out the navigation bar to avoid flakiness with button animations.
int navigationBarHeight = getNavigationBarHeight();
- // Crop the right side for scrollbar which might or might not be visible. On wearable
- // devices the scroll bar is a curve and occupies 20% of the right side.
+ // Crop-out the right side for the scrollbar which may or may not be visible.
+ // On wearable devices the scroll bar is a curve and occupies 20% of the right side.
int xToCut = isOnWatchUiMode() ? bt.getWidth() / 5 : bt.getWidth() / 20;
bt = Bitmap.createBitmap(
@@ -77,142 +73,45 @@
return bt;
}
- void tapOnViewWithText(String searchText) {
- if (searchText == null) {
- return;
+ void tapOnViewWithText(String text) {
+ UiObject2 object = getTextObject(text);
+ if (object == null) {
+ throw new AssertionError("View with text '" + text + "' was not found!");
}
-
- try {
- // If the current UI has shown text, just click on it.
- UiObject text = new UiObject(new UiSelector().text(searchText));
- if (text.exists() || text.waitForExists(1000)) {
- text.click();
- return;
- }
-
- // Otherwise, if it is scrollable, scroll to where the text is and tap.
- UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));
-
- textScroll.scrollIntoView(new UiSelector().text(searchText));
- text = new UiObject(new UiSelector().text(searchText));
- text.click();
- } catch (UiObjectNotFoundException e) {
- throw new AssertionError("View with text '" + searchText + "' was not found!", e);
- }
+ object.click();
}
- boolean isTextShown(String searchText) {
- if (searchText == null) {
- return false;
- }
-
- UiObject text = new UiObject(new UiSelector().text(searchText));
- if (text.exists() || text.waitForExists(1000)) {
- return true;
- }
-
- UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));
- try {
- return textScroll.scrollIntoView(new UiSelector().text(searchText));
- } catch (UiObjectNotFoundException e) {
- return false;
- }
+ boolean isTextShown(String text) {
+ return getTextObject(text) != null;
}
boolean isTextHidden(String text) {
- UiObject obj = device.findObject(new UiSelector().textMatches(text));
- if (!obj.exists()) {
- return true;
- }
- return obj.waitUntilGone(1000);
+ return getTextObject(text) == null;
}
boolean isTextFocused(String text) {
- UiObject obj = device.findObject(new UiSelector().textMatches(text));
- try {
- return obj.isFocused();
- } catch (UiObjectNotFoundException e) {
- return false;
- }
+ UiObject2 object = getTextObject(text);
+ return object != null && object.isFocused();
}
boolean isOnWatchUiMode() {
- Context context = mInstrumentation.getTargetContext();
- UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
+ UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_WATCH;
}
- void getMultiWindowFocus(Context context) {
- // Get window focus (otherwise back press would close multi-window instead of firing to the
- // Activity and also the automator would fail to find objects on the screen.
- // We want to click slightly below status bar in the 1/3 of width of the screen.
- int x = device.getDisplayWidth() / 3;
- int resourceId =
- context.getResources().getIdentifier("status_bar_height", "dimen", "android");
- int statusBarHeight =
- (resourceId > 0) ? context.getResources().getDimensionPixelSize(resourceId) : 0;
- device.click(x, 2 * statusBarHeight);
- }
-
- // Multi-window helpers taken from ActivityManagerDockedStackTests.java
-
- void enterMultiWindow(Activity activity) {
- try {
- int id = getActivityTaskId(activity);
- runShellCommand("am stack move-task " + id + " 3 true");
- } catch (IOException e) {
- throw new RuntimeException("Failed to get activity task id!", e);
- }
- SystemClock.sleep(5000);
- }
-
- void leaveMultiWindow(Activity activity) {
- try {
- int id = getActivityTaskId(activity);
- runShellCommand("am stack move-task " + id + " 1 true");
- } catch (IOException e) {
- throw new RuntimeException("Failed to get activity task id!", e);
- }
- SystemClock.sleep(5000);
- }
-
- private int getActivityTaskId(Activity activity) throws IOException {
- // Taken from ActivityManagerTestBase.java
- final String output = runShellCommand("am stack list");
- final Pattern activityPattern =
- Pattern.compile("(.*) " + getWindowName(activity) + " (.*)");
- for (String line : output.split("\\n")) {
- Matcher matcher = activityPattern.matcher(line);
- if (matcher.matches()) {
- for (String word : line.split("\\s+")) {
- if (word.startsWith("taskId")) {
- final String withColon = word.split("=")[1];
- return Integer.parseInt(withColon.substring(0, withColon.length() - 1));
- }
- }
- }
- }
- return -1;
- }
-
- private String getWindowName(Activity activity) {
- String componentName = activity.getPackageName();
- String baseWindowName = componentName + "/" + componentName + ".";
- return baseWindowName + activity.getClass().getSimpleName();
- }
-
private int getStatusBarHeight() {
// Cache the result to keep it fast.
if (mStatusBarHeight >= 0) {
return mStatusBarHeight;
}
- mStatusBarHeight = 0;
int resourceId = mInstrumentation.getTargetContext().getResources()
.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
mStatusBarHeight = mInstrumentation.getTargetContext().getResources()
.getDimensionPixelSize(resourceId);
+ } else {
+ mStatusBarHeight = 0;
}
return mStatusBarHeight;
}
@@ -223,21 +122,19 @@
return mNavigationBarHeight;
}
- mNavigationBarHeight = 0;
int resourceId = mInstrumentation.getTargetContext().getResources()
.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
mNavigationBarHeight = mInstrumentation.getTargetContext().getResources()
.getDimensionPixelSize(resourceId);
+ } else {
+ mNavigationBarHeight = 0;
}
return mNavigationBarHeight;
}
- private String runShellCommand(String cmd) {
- try {
- return SystemUtil.runShellCommand(mInstrumentation, cmd);
- } catch (IOException e) {
- throw new RuntimeException("Failed to run command: " + cmd, e);
- }
+ private UiObject2 getTextObject(String text) {
+ // Wait for up to 1 second to find the object. Returns null if the object cannot be found.
+ return device.wait(Until.findObject(By.text(text).pkg(mPackageName)), 1000);
}
}
diff --git a/tests/tests/slice/Android.mk b/tests/tests/slice/Android.mk
index fd041ea..46f1e9a 100644
--- a/tests/tests/slice/Android.mk
+++ b/tests/tests/slice/Android.mk
@@ -44,7 +44,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSliceTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_SDK_VERSION := test_current
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/slice/src/android/slice/cts/LocalSliceProvider.java b/tests/tests/slice/src/android/slice/cts/LocalSliceProvider.java
index 53b13cb..b6c162b 100644
--- a/tests/tests/slice/src/android/slice/cts/LocalSliceProvider.java
+++ b/tests/tests/slice/src/android/slice/cts/LocalSliceProvider.java
@@ -47,7 +47,7 @@
@Override
public void attachInfo(Context context, ProviderInfo info) {
mSliceService = mock(SliceManager.class, withSettings()
- .spiedInstance(context.getSystemService(Context.SLICE_SERVICE))
+ .spiedInstance(context.getSystemService(SliceManager.class))
.defaultAnswer(invocation -> {
Answer s = sAnswer != null ? sAnswer : Answers.CALLS_REAL_METHODS;
return s.answer(invocation);
@@ -55,7 +55,7 @@
Context wrapped = new ContextWrapper(context) {
@Override
public Object getSystemService(String name) {
- if (Context.SLICE_SERVICE.equals(name)) {
+ if (getSystemServiceName(SliceManager.class).equals(name)) {
return mSliceService;
}
return super.getSystemService(name);
diff --git a/tests/tests/text/src/android/text/cts/MyanmarTest.java b/tests/tests/text/src/android/text/cts/MyanmarTest.java
index 8a71adb..916b451 100644
--- a/tests/tests/text/src/android/text/cts/MyanmarTest.java
+++ b/tests/tests/text/src/android/text/cts/MyanmarTest.java
@@ -19,16 +19,20 @@
import static org.junit.Assert.assertTrue;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
import android.widget.TextView;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Locale;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class MyanmarTest {
@@ -38,6 +42,21 @@
@UiThreadTest
@Test
public void testCompositionSemantics() {
+ boolean isMyanmarSupported = false;
+ final String[] localeNames = Resources.getSystem().getStringArray(
+ Resources.getSystem().getIdentifier("supported_locales", "array", "android"));
+ for (String localeName : localeNames) {
+ if (TextUtils.equals("my", Locale.forLanguageTag(localeName).getLanguage())) {
+ isMyanmarSupported = true;
+ break;
+ }
+ }
+ if (!isMyanmarSupported) {
+ // Ignoring since no Myanmar font guarantee if Myanmar is not listed in supported
+ // locales.
+ return;
+ }
+
Context context = InstrumentationRegistry.getTargetContext();
String textA = "\u1019\u102d\u102f";
String textB = "\u1019\u102f\u102d"; // wrong order for Unicode
diff --git a/tests/tests/text/src/android/text/cts/PrecomputedTextTest.java b/tests/tests/text/src/android/text/cts/PrecomputedTextTest.java
index 9491eff..7b42687 100644
--- a/tests/tests/text/src/android/text/cts/PrecomputedTextTest.java
+++ b/tests/tests/text/src/android/text/cts/PrecomputedTextTest.java
@@ -26,6 +26,8 @@
import static org.junit.Assert.fail;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -43,6 +45,10 @@
import android.text.style.BackgroundColorSpan;
import android.text.style.LocaleSpan;
import android.text.style.TextAppearanceSpan;
+import android.text.style.TypefaceSpan;
+
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -620,4 +626,82 @@
PrecomputedText.create("a\nb", param).getBounds(0, 3, rect);
}
+ private static Bitmap drawToBitmap(@NonNull CharSequence cs,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+ @IntRange(from = 0) int ctxStart, @IntRange(from = 0) int ctxEnd,
+ @NonNull TextPaint paint) {
+
+ Rect rect = new Rect();
+ paint.getTextBounds(cs.toString(), start, end, rect);
+ final Bitmap bmp = Bitmap.createBitmap(rect.width(),
+ rect.height(), Bitmap.Config.ARGB_8888);
+ final Canvas c = new Canvas(bmp);
+ c.save();
+ c.translate(0, 0);
+ c.drawTextRun(cs, start, end, ctxStart, ctxEnd, 0, 0, false /* isRtl */, paint);
+ c.restore();
+ return bmp;
+ }
+
+ private static void assertSameOutput(@NonNull CharSequence cs,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+ @IntRange(from = 0) int ctxStart, @IntRange(from = 0) int ctxEnd,
+ @NonNull TextPaint paint) {
+ final Params params = new Params.Builder(paint).build();
+ final PrecomputedText pt = PrecomputedText.create(cs, params);
+
+ final Bitmap originalDrawOutput = drawToBitmap(cs, start, end, ctxStart, ctxEnd, paint);
+ final Bitmap precomputedDrawOutput = drawToBitmap(pt, start, end, ctxStart, ctxEnd, paint);
+ assertTrue(originalDrawOutput.sameAs(precomputedDrawOutput));
+ }
+
+ @Test
+ public void testDrawText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(32.0f);
+
+ final SpannableStringBuilder ssb = new SpannableStringBuilder("Hello, World");
+ assertSameOutput(ssb, 0, ssb.length(), 0, ssb.length(), paint);
+ assertSameOutput(ssb, 3, ssb.length() - 3, 0, ssb.length(), paint);
+ assertSameOutput(ssb, 5, ssb.length() - 5, 2, ssb.length() - 2, paint);
+ }
+
+ @Test
+ public void testDrawText_MultiStyle() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(32.0f);
+
+ final SpannableStringBuilder ssb = new SpannableStringBuilder("Hello, World");
+ ssb.setSpan(new TypefaceSpan("serif"), 0, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ assertSameOutput(ssb, 0, ssb.length(), 0, ssb.length(), paint);
+ assertSameOutput(ssb, 3, ssb.length() - 3, 0, ssb.length(), paint);
+ assertSameOutput(ssb, 5, ssb.length() - 5, 2, ssb.length() - 2, paint);
+ }
+
+ @Test
+ public void testDrawText_MultiParagraph() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(32.0f);
+
+ final SpannableStringBuilder ssb = new SpannableStringBuilder(
+ "Hello, World\nHello, Android");
+
+ // The first line
+ final int firstLineLen = "Hello, World\n".length();
+ assertSameOutput(ssb, 0, firstLineLen, 0, firstLineLen, paint);
+ assertSameOutput(ssb, 3, firstLineLen - 3, 0, firstLineLen, paint);
+ assertSameOutput(ssb, 3, firstLineLen - 3, 2, firstLineLen - 2, paint);
+
+ // The second line.
+ assertSameOutput(ssb, firstLineLen, ssb.length(), firstLineLen, ssb.length(), paint);
+ assertSameOutput(ssb, firstLineLen + 3, ssb.length() - 3,
+ firstLineLen, ssb.length(), paint);
+ assertSameOutput(ssb, firstLineLen + 5, ssb.length() - 5,
+ firstLineLen + 2, ssb.length() - 2, paint);
+
+ // Across the paragraph
+ assertSameOutput(ssb, 0, ssb.length(), 0, ssb.length(), paint);
+ assertSameOutput(ssb, 3, firstLineLen - 3, 0, ssb.length(), paint);
+ assertSameOutput(ssb, 3, firstLineLen - 3, 2, ssb.length() - 2, paint);
+ }
}
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java b/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java
index 489fb2d..9fed9ee 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionSetTest.java
@@ -18,18 +18,28 @@
import static com.android.compatibility.common.util.CtsMockitoUtils.within;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.animation.TimeInterpolator;
+import android.graphics.Rect;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import android.transition.ArcMotion;
import android.transition.ChangeBounds;
import android.transition.Fade;
+import android.transition.PathMotion;
import android.transition.Transition;
+import android.transition.TransitionPropagation;
import android.transition.TransitionSet;
+import android.transition.TransitionValues;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -123,5 +133,119 @@
assertEquals(1, transitionSet.getTransitionCount());
assertSame(changeBounds, transitionSet.getTransitionAt(0));
}
+
+ @Test
+ public void testSetTransferValuesDuringAdd() throws Throwable {
+ Fade fade = new Fade();
+ fade.setDuration(500);
+ fade.setPropagation(new TestPropagation());
+ fade.setEpicenterCallback(new Transition.EpicenterCallback() {
+ @Override
+ public Rect onGetEpicenter(Transition transition) {
+ return null;
+ }
+ });
+ fade.setInterpolator(new AccelerateDecelerateInterpolator());
+ fade.setPathMotion(new ArcMotion());
+
+ TransitionSet transitionSet = new TransitionSet();
+ int duration = 100;
+ TestPropagation propagation = new TestPropagation();
+ TimeInterpolator interpolator = new DecelerateInterpolator();
+ PathMotion pathMotion = new ArcMotion();
+ Transition.EpicenterCallback epicenterCallback = new Transition.EpicenterCallback() {
+ @Override
+ public Rect onGetEpicenter(Transition transition) {
+ return null;
+ }
+ };
+ transitionSet.setDuration(duration);
+ transitionSet.setPropagation(propagation);
+ transitionSet.setInterpolator(interpolator);
+ transitionSet.setPathMotion(pathMotion);
+ transitionSet.setEpicenterCallback(epicenterCallback);
+
+ transitionSet.addTransition(fade);
+ assertEquals(duration, fade.getDuration());
+ assertSame(propagation, fade.getPropagation());
+ assertSame(interpolator, fade.getInterpolator());
+ assertSame(pathMotion, fade.getPathMotion());
+ assertSame(epicenterCallback, fade.getEpicenterCallback());
+ }
+
+ @Test
+ public void testSetTransferNullValuesDuringAdd() throws Throwable {
+ Fade fade = new Fade();
+ fade.setDuration(500);
+ fade.setPropagation(new TestPropagation());
+ fade.setEpicenterCallback(new Transition.EpicenterCallback() {
+ @Override
+ public Rect onGetEpicenter(Transition transition) {
+ return null;
+ }
+ });
+ fade.setInterpolator(new AccelerateDecelerateInterpolator());
+ fade.setPathMotion(new ArcMotion());
+
+ TransitionSet transitionSet = new TransitionSet();
+ transitionSet.setDuration(0);
+ transitionSet.setPropagation(null);
+ transitionSet.setInterpolator(null);
+ transitionSet.setPathMotion(null);
+ transitionSet.setEpicenterCallback(null);
+
+ transitionSet.addTransition(fade);
+ assertEquals(0, fade.getDuration());
+ assertNull(fade.getPropagation());
+ assertNull(fade.getInterpolator());
+ assertSame(transitionSet.getPathMotion(), fade.getPathMotion());
+ assertNull(fade.getEpicenterCallback());
+ }
+
+ @Test
+ public void testSetNoTransferValuesDuringAdd() throws Throwable {
+ Fade fade = new Fade();
+ int duration = 100;
+ TestPropagation propagation = new TestPropagation();
+ TimeInterpolator interpolator = new DecelerateInterpolator();
+ PathMotion pathMotion = new ArcMotion();
+ Transition.EpicenterCallback epicenterCallback = new Transition.EpicenterCallback() {
+ @Override
+ public Rect onGetEpicenter(Transition transition) {
+ return null;
+ }
+ };
+ fade.setDuration(duration);
+ fade.setPropagation(propagation);
+ fade.setInterpolator(interpolator);
+ fade.setPathMotion(pathMotion);
+ fade.setEpicenterCallback(epicenterCallback);
+
+ TransitionSet transitionSet = new TransitionSet();
+
+ transitionSet.addTransition(fade);
+ assertEquals(duration, fade.getDuration());
+ assertSame(propagation, fade.getPropagation());
+ assertSame(interpolator, fade.getInterpolator());
+ assertSame(pathMotion, fade.getPathMotion());
+ assertSame(epicenterCallback, fade.getEpicenterCallback());
+ }
+
+ private static class TestPropagation extends TransitionPropagation {
+ @Override
+ public long getStartDelay(ViewGroup sceneRoot, Transition transition,
+ TransitionValues startValues, TransitionValues endValues) {
+ return 0;
+ }
+
+ @Override
+ public void captureValues(TransitionValues transitionValues) {
+ }
+
+ @Override
+ public String[] getPropagationProperties() {
+ return new String[] { };
+ }
+ }
}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
index f4db101..1368420 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/VectorDrawableTests.java
@@ -16,9 +16,6 @@
package android.uirendering.cts.testclasses;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -31,14 +28,15 @@
import android.uirendering.cts.bitmapverifiers.RectVerifier;
import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-
-import android.uirendering.cts.testinfrastructure.ViewInitializer;
+import android.view.Gravity;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
+
import org.junit.Test;
import org.junit.runner.RunWith;
+
import java.util.concurrent.CountDownLatch;
-import android.animation.Animator;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -82,68 +80,51 @@
*/
@Test
public void testInvalidateCache() {
- CountDownLatch testFinishedFence = new CountDownLatch(1);
-
- ViewInitializer initializer = new ViewInitializer() {
- ValueAnimator mAnimator;
-
- @Override
- public void initializeView(View view) {
- FrameLayout root = (FrameLayout) view.findViewById(R.id.frame_layout);
- root.setBackgroundColor(Color.BLUE);
-
- final VectorDrawableView child = new VectorDrawableView(view.getContext());
-
- child.setLayoutParams(new FrameLayout.LayoutParams(ActivityTestBase.TEST_WIDTH,
- ActivityTestBase.TEST_HEIGHT));
- // VectorDrawable is a red circle drawn on top of a blue background.
- // The first frame has VectorDrawable size set to 1x1 pixels, which deforms
- // the red circle into a 1x1 red-ish square.
- // An animation grows VectorDrawable bounds from 0x0 to 90x90. If VD cache is
- // refreshed, then we should see a red circle on top of a blue background.
- // If VD cache is stale, then VD will upscale the original 1x1 cached image to
- // 90x90 red-ish square.
- // At the end of the animation, we verify the color of top left pixel, which should
- // be a blue background pixel.
- child.setVDSize(new Rect(0, 0, 2, 2)); //first draw with VD size set to 1x1 pixels.
- root.addView(child);
-
- mAnimator = ValueAnimator.ofFloat(0, 1);
- mAnimator.setRepeatCount(0);
- mAnimator.setDuration(400);
- mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float progress = (float) mAnimator.getAnimatedValue();
- child.setVDSize(new Rect(0, 0, (int)(progress*child.getWidth()),
- (int)(progress*child.getHeight())));
- child.invalidate();
- }
- });
- mAnimator.addListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- testFinishedFence.countDown();
- }
- });
-
- mAnimator.start();
- }
-
- @Override
- public void teardownView() {
- mAnimator.cancel();
- }
- };
-
+ final CountDownLatch fence = new CountDownLatch(1);
createTest()
- .addLayout(R.layout.frame_layout, initializer, true, testFinishedFence)
- .runWithVerifier(new SamplePointVerifier(
- new Point[] { new Point(0, 0) },
- new int[] { 0xff0000ff }
- ));
+ .addLayout(R.layout.frame_layout, view -> {
+ FrameLayout root = (FrameLayout) view.findViewById(R.id.frame_layout);
+ root.setBackgroundColor(Color.BLUE);
+ final VectorDrawableView child = new VectorDrawableView(view.getContext());
+ // VectorDrawable is a red circle drawn on top of a blue background.
+ // The first frame has VectorDrawable size set to 1x1 pixels, which deforms
+ // the red circle into a 1x1 red-ish square.
+ // After first draw we grow VectorDrawable bounds from 0x0 to 90x90. If VD cache
+ // is refreshed, then we should see a red circle on top of a blue background.
+ // If VD cache is stale, then VD will upscale the original 1x1 cached image to
+ // 90x90 red-ish square.
+ // At the end we verify the color of top left pixel, which should be a blue
+ // background pixel.
+ child.setVDSize(new Rect(0, 0, 2, 2));
+
+ root.addView(child, new FrameLayout.LayoutParams(TEST_WIDTH, TEST_HEIGHT,
+ Gravity.TOP | Gravity.LEFT));
+
+ // Post a new VD size a few frames in, so that the initial draw completes.
+ root.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ int mDrawCount = 0;
+ @Override
+ public boolean onPreDraw() {
+ if (mDrawCount++ == 5) {
+ child.setVDSize(new Rect(0, 0,
+ (int) (child.getWidth()),
+ (int) (child.getHeight())));
+ child.invalidate();
+
+ root.getViewTreeObserver().removeOnPreDrawListener(this);
+ root.post(fence::countDown);
+ } else {
+ root.postInvalidate();
+ }
+ return true;
+ }
+ });
+ }, true, fence)
+ .runWithVerifier(new SamplePointVerifier(
+ new Point[] { new Point(0, 0) },
+ new int[] { 0xff0000ff }
+ ));
}
}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/util/WebViewReadyHelper.java b/tests/tests/uirendering/src/android/uirendering/cts/util/WebViewReadyHelper.java
index 22ee9ca..339e2f0 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/util/WebViewReadyHelper.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/util/WebViewReadyHelper.java
@@ -10,6 +10,7 @@
public final class WebViewReadyHelper {
private final CountDownLatch mLatch;
private final WebView mWebView;
+ private int mDrawCount = 0;
public WebViewReadyHelper(WebView webview, CountDownLatch latch) {
mWebView = webview;
@@ -38,6 +39,10 @@
private OnDrawListener mOnDrawListener = new OnDrawListener() {
@Override
public void onDraw() {
+ if (++mDrawCount < 2) {
+ mWebView.postInvalidate();
+ return;
+ }
mWebView.post(() -> {
mWebView.getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
mLatch.countDown();
diff --git a/tests/tests/view/src/android/view/cts/KeyEventInterceptTest.java b/tests/tests/view/src/android/view/cts/KeyEventInterceptTest.java
index 598552b..3045d1f2 100644
--- a/tests/tests/view/src/android/view/cts/KeyEventInterceptTest.java
+++ b/tests/tests/view/src/android/view/cts/KeyEventInterceptTest.java
@@ -16,6 +16,7 @@
package android.view.cts;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.app.Instrumentation;
@@ -34,16 +35,20 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.concurrent.TimeUnit;
-
/**
* Certain KeyEvents should never be delivered to apps. These keys are:
* KEYCODE_ASSIST
* KEYCODE_VOICE_ASSIST
* KEYCODE_HOME
- * This test launches an Activity and inject KeyEvents with the corresponding key codes.
+ * This test launches an Activity and injects KeyEvents with the corresponding key codes.
* The test will fail if any of these keys are received by the activity.
+ *
+ * Certain combinations of keys should be treated as shortcuts. Those are:
+ * KEYCODE_META_* + KEYCODE_ENTER --> KEYCODE_BACK
+ * KEYCODE_META_* + KEYCODE_DEL --> KEYCODE_HOME
+ * For those combinations, we make sure that they are either delivered to the app
+ * as the desired key (KEYCODE_BACK), or not delivered to the app (KEYCODE_HOME).
*/
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -77,6 +82,48 @@
testKey(KeyEvent.KEYCODE_HOME);
}
+ @Test
+ public void testKeyCodeHomeShortcutLeftMeta() {
+ testKeyCodeHomeShortcut(KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON);
+ }
+
+ @Test
+ public void testKeyCodeHomeShortcutRightMeta() {
+ testKeyCodeHomeShortcut(KeyEvent.META_META_RIGHT_ON | KeyEvent.META_META_ON);
+ }
+
+ @Test
+ public void testKeyCodeBackShortcutLeftMeta() {
+ testKeyCodeBackShortcut(KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON);
+ }
+
+ @Test
+ public void testKeyCodeBackShortcutRightMeta() {
+ testKeyCodeBackShortcut(KeyEvent.META_META_RIGHT_ON | KeyEvent.META_META_ON);
+ }
+
+ private void testKeyCodeHomeShortcut(int metaState) {
+ long downTime = SystemClock.uptimeMillis();
+ injectEvent(new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_ENTER, 0, metaState));
+ injectEvent(new KeyEvent(downTime, downTime + 1, KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_ENTER, 0, metaState));
+
+ assertKeyNotReceived();
+ }
+
+ private void testKeyCodeBackShortcut(int metaState) {
+ long downTime = SystemClock.uptimeMillis();
+ injectEvent(new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_DEL, 0, metaState));
+ injectEvent(new KeyEvent(downTime, downTime + 1, KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_DEL, 0, metaState));
+
+ assertKeyReceived(KeyEvent.KEYCODE_BACK, KeyEvent.ACTION_DOWN);
+ assertKeyReceived(KeyEvent.KEYCODE_BACK, KeyEvent.ACTION_UP);
+ assertKeyNotReceived();
+ }
+
private void testKey(int keyCode) {
sendKey(keyCode);
assertKeyNotReceived();
@@ -97,14 +144,19 @@
}
private void assertKeyNotReceived() {
- try {
- KeyEvent keyEvent = mActivity.mKeyEvents.poll(1, TimeUnit.SECONDS);
- if (keyEvent == null) {
- return;
- }
- fail("Should not have received " + KeyEvent.keyCodeToString(keyEvent.getKeyCode()));
- } catch (InterruptedException ex) {
- fail("BlockingQueue.poll(..) was unexpectedly interrupted");
+ KeyEvent keyEvent = mActivity.mKeyEvents.poll();
+ if (keyEvent == null) {
+ return;
}
+ fail("Should not have received " + KeyEvent.keyCodeToString(keyEvent.getKeyCode()));
+ }
+
+ private void assertKeyReceived(int keyCode, int action) {
+ KeyEvent keyEvent = mActivity.mKeyEvents.poll();
+ if (keyEvent == null) {
+ fail("Did not receive " + KeyEvent.keyCodeToString(keyCode) + ", queue is empty");
+ }
+ assertEquals(keyCode, keyEvent.getKeyCode());
+ assertEquals(action, keyEvent.getAction());
}
}
diff --git a/tests/tests/view/src/android/view/cts/KeyEventInterceptTestActivity.java b/tests/tests/view/src/android/view/cts/KeyEventInterceptTestActivity.java
index 18e0713..2422a61 100644
--- a/tests/tests/view/src/android/view/cts/KeyEventInterceptTestActivity.java
+++ b/tests/tests/view/src/android/view/cts/KeyEventInterceptTestActivity.java
@@ -19,21 +19,14 @@
import android.app.Activity;
import android.view.KeyEvent;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingDeque;
+import java.util.LinkedList;
+import java.util.Queue;
public class KeyEventInterceptTestActivity extends Activity {
- final BlockingQueue<KeyEvent> mKeyEvents = new LinkedBlockingDeque<>();
+ final Queue<KeyEvent> mKeyEvents = new LinkedList<>();
@Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- mKeyEvents.add(event);
- return true;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- // Check this in case some spurious event with ACTION_UP is received
+ public boolean dispatchKeyEvent(KeyEvent event) {
mKeyEvents.add(event);
return true;
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 6d61e1c..a2a33c4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -725,6 +725,21 @@
assertEquals("No database", mOnUiThread.getTitle());
}
+ public void testDisabledActionModeMenuItems() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ assertEquals(WebSettings.MENU_ITEM_NONE, mSettings.getDisabledActionModeMenuItems());
+
+ int allDisabledFlags = WebSettings.MENU_ITEM_NONE | WebSettings.MENU_ITEM_SHARE |
+ WebSettings.MENU_ITEM_WEB_SEARCH | WebSettings.MENU_ITEM_PROCESS_TEXT;
+ for (int i = WebSettings.MENU_ITEM_NONE; i <= allDisabledFlags; i++) {
+ mSettings.setDisabledActionModeMenuItems(i);
+ assertEquals(i, mSettings.getDisabledActionModeMenuItems());
+ }
+ }
+
public void testLoadsImagesAutomatically() throws Throwable {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 58e59e5..f66b371 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -43,6 +43,8 @@
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
@@ -604,20 +606,23 @@
assertFalse(webViewClient.didRenderProcessCrash());
}
- public void testOnSafeBrowsingHit() throws Throwable {
+ public void testOnSafeBrowsingHitBackToSafety() throws Throwable {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
}
- final SafeBrowsingBackToSafetyClient backToSafetyWebViewClient =
- new SafeBrowsingBackToSafetyClient();
- mOnUiThread.setWebViewClient(backToSafetyWebViewClient);
- mOnUiThread.getSettings().setSafeBrowsingEnabled(true);
-
mWebServer = new CtsTestServer(getActivity());
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
final String ORIGINAL_URL = mOnUiThread.getUrl();
+ final SafeBrowsingBackToSafetyClient backToSafetyWebViewClient =
+ new SafeBrowsingBackToSafetyClient();
+ mOnUiThread.setWebViewClient(backToSafetyWebViewClient);
+ mOnUiThread.getSettings().setSafeBrowsingEnabled(true);
+
+ // Note: Safe Browsing depends on user opt-in as well, so we can't assume it's actually
+ // enabled. #getSafeBrowsingEnabled will tell us the true state of whether Safe Browsing is
+ // enabled.
if (mOnUiThread.getSettings().getSafeBrowsingEnabled()) {
assertEquals(0, backToSafetyWebViewClient.hasOnReceivedErrorCode());
mOnUiThread.loadUrlAndWaitForCompletion(TEST_SAFE_BROWSING_URL);
@@ -633,11 +638,25 @@
// Check that we actually navigated backward
assertEquals(ORIGINAL_URL, mOnUiThread.getUrl());
}
+ }
- final SafeBrowsingProceedClient proceedWebViewClient = new SafeBrowsingProceedClient();
+ public void testOnSafeBrowsingHitProceed() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ mWebServer = new CtsTestServer(getActivity());
+ String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ final String ORIGINAL_URL = mOnUiThread.getUrl();
+
+ final SafeBrowsingProceedClient proceedWebViewClient =
+ new SafeBrowsingProceedClient();
mOnUiThread.setWebViewClient(proceedWebViewClient);
-
mOnUiThread.getSettings().setSafeBrowsingEnabled(true);
+
+ // Note: Safe Browsing depends on user opt-in as well, so we can't assume it's actually
+ // enabled. #getSafeBrowsingEnabled will tell us the true state of whether Safe Browsing is
+ // enabled.
if (mOnUiThread.getSettings().getSafeBrowsingEnabled()) {
assertEquals(0, proceedWebViewClient.hasOnReceivedErrorCode());
mOnUiThread.loadUrlAndWaitForCompletion(TEST_SAFE_BROWSING_URL);
@@ -658,6 +677,26 @@
mOnUiThread.loadUrlAndWaitForCompletion("about:blank");
}
+ public void testOnPageCommitVisibleCalled() throws Exception {
+ // Check that the onPageCommitVisible callback is called
+ // correctly.
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ final CountDownLatch callbackLatch = new CountDownLatch(1);
+
+ mOnUiThread.setWebViewClient(new WebViewClient() {
+ public void onPageCommitVisible(WebView view, String url) {
+ assertEquals(url, "about:blank");
+ callbackLatch.countDown();
+ }
+ });
+
+ mOnUiThread.loadUrl("about:blank");
+ assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
+ }
+
private class MockWebViewClient extends WaitForLoadedClient {
private boolean mOnPageStartedCalled;
private boolean mOnPageFinishedCalled;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 4bedbb1..e6ff32b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1361,7 +1361,7 @@
assertNull(mWebView.getUrl());
String imgUrl = TestHtmlConstants.SMALL_IMG_URL; // relative
// Snippet of HTML that will prevent favicon requests to the test server.
- final String HTML_HEADER = "<html><head><link rel=\"shortcut icon\" href=\"#\" /></head>";
+ final String HTML_HEADER = "<html><head><link rel=\"shortcut icon\" href=\"%23\" /></head>";
// Trying to resolve a relative URL against a data URL without a base URL
// will fail and we won't make a request to the test web server.
@@ -1968,8 +1968,8 @@
final String imgUrl = mWebServer.getAssetUrl(TestHtmlConstants.LARGE_IMG_URL);
mOnUiThread.loadDataAndWaitForCompletion(
"<html><head><title>Title</title><style type=\"text/css\">"
- + "#imgElement { -webkit-transform: translate3d(0,0,1); }"
- + "#imgElement.finish { -webkit-transform: translate3d(0,0,0);"
+ + "%23imgElement { -webkit-transform: translate3d(0,0,1); }"
+ + "%23imgElement.finish { -webkit-transform: translate3d(0,0,0);"
+ " -webkit-transition-duration: 1ms; }</style>"
+ "<script type=\"text/javascript\">function imgLoad() {"
+ "imgElement = document.getElementById('imgElement');"
@@ -2656,26 +2656,6 @@
assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
}
- public void testOnPageCommitVisibleCalled() throws Exception {
- // Check that the onPageCommitVisible callback is called
- // correctly.
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
-
- final CountDownLatch callbackLatch = new CountDownLatch(1);
-
- mOnUiThread.setWebViewClient(new WebViewClient() {
- public void onPageCommitVisible(WebView view, String url) {
- assertEquals(url, "about:blank");
- callbackLatch.countDown();
- }
- });
-
- mOnUiThread.loadUrl("about:blank");
- assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
- }
-
public void testSetSafeBrowsingWhitelistWithMalformedList() throws Exception {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
diff --git a/tests/tests/widget/res/values/strings.xml b/tests/tests/widget/res/values/strings.xml
index 78f0f7c..9e36cc0 100644
--- a/tests/tests/widget/res/values/strings.xml
+++ b/tests/tests/widget/res/values/strings.xml
@@ -197,6 +197,7 @@
<string name="toolbar_subtitle">Toolbar subtitle</string>
<string name="toolbar_navigation">Toolbar navigation</string>
<string name="toolbar_logo">Toolbar logo</string>
+ <string name="toolbar_collapse">Toolbar collapse</string>
<string name="search_query_hint">query hint</string>
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
index 5476b22..d59fe97 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
@@ -33,6 +33,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.annotation.Nullable;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -42,13 +43,19 @@
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
+import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.PaintDrawable;
import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
@@ -500,6 +507,46 @@
verify(mockImageView, times(1)).onSizeChanged(anyInt(), anyInt(), anyInt(), anyInt());
}
+ @Test
+ public void testSetColorFilterPreservesDrawableProperties() {
+ ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext());
+
+ int colorAlpha = 128;
+ MockDrawable mockDrawable = new MockDrawable();
+ mockDrawable.setAlpha(colorAlpha);
+ mockDrawable.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
+
+ imageView.setImageDrawable(mockDrawable);
+
+ imageView.setColorFilter(Color.RED);
+ assertEquals(colorAlpha, mockDrawable.getAlpha());
+ assertNotNull(mockDrawable.getXfermode());
+ }
+
+ @Test
+ public void testImageViewSetColorFilterPropagatedToDrawable() {
+ ImageView imageView = new ImageView(InstrumentationRegistry.getTargetContext());
+
+ MockDrawable mockDrawable = new MockDrawable();
+ imageView.setImageDrawable(mockDrawable);
+ imageView.setColorFilter(Color.RED);
+
+ ColorFilter imageViewColorFilter = imageView.getColorFilter();
+ assertTrue(imageViewColorFilter instanceof PorterDuffColorFilter);
+
+ PorterDuffColorFilter imageViewPorterDuffFilter =
+ (PorterDuffColorFilter) imageViewColorFilter;
+ assertEquals(Color.RED, imageViewPorterDuffFilter.getColor());
+ assertEquals(Mode.SRC_ATOP, imageViewPorterDuffFilter.getMode());
+
+ ColorFilter colorFilter = mockDrawable.getColorFilter();
+ assertTrue(colorFilter instanceof PorterDuffColorFilter);
+
+ PorterDuffColorFilter porterDuffColorFilter = (PorterDuffColorFilter) colorFilter;
+ assertEquals(Color.RED, porterDuffColorFilter.getColor());
+ assertEquals(PorterDuff.Mode.SRC_ATOP, porterDuffColorFilter.getMode());
+ }
+
@UiThreadTest
@Test
public void testVerifyDrawable() {
@@ -674,4 +721,49 @@
super.onSizeChanged(w, h, oldw, oldh);
}
}
+
+ public static class MockDrawable extends Drawable {
+
+ private ColorFilter mFilter;
+ private int mAlpha;
+ private Xfermode mXfermode;
+
+ @Override
+ public void draw(Canvas canvas) {
+ // NO-OP
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mAlpha = alpha;
+ }
+
+ public int getAlpha() {
+ return mAlpha;
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mFilter = colorFilter;
+ }
+
+ @Override
+ public void setXfermode(Xfermode mode) {
+ mXfermode = mode;
+ }
+
+ public @Nullable Xfermode getXfermode() {
+ return mXfermode;
+ }
+
+ @Override
+ public @Nullable ColorFilter getColorFilter() {
+ return mFilter;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java b/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
index 282ee5f..ffa5a28 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewPrecomputedTextTest.java
@@ -61,15 +61,15 @@
@Parameterized.Parameter(5)
public boolean differentTypeface;
@Parameterized.Parameter(6)
- public boolean differentFontVariationSettings;
- @Parameterized.Parameter(7)
public boolean differentElegantTextHeight;
- @Parameterized.Parameter(8)
+ @Parameterized.Parameter(7)
public boolean differentBreakStrategy;
- @Parameterized.Parameter(9)
+ @Parameterized.Parameter(8)
public boolean differentHyphenationFrequency;
- @Parameterized.Parameter(10)
+ @Parameterized.Parameter(9)
public boolean differentTextDir;
+ @Parameterized.Parameter(10)
+ public boolean differentFontVariationSettings;
// text size from the default value.
private Pair<Params, String[]> makeDifferentParams(Params params) {
@@ -156,8 +156,12 @@
ArrayList<Object[]> allParams = new ArrayList<>();
// Compute the powerset except for all false case.
- int allParameterCount = 11;
- for (int bits = 1; bits < (1 << allParameterCount); ++bits) {
+ final int allParameterCount = 11;
+ // The 11-th bit is for font variation settings. Don't add test case if the system don't
+ // have variable fonts.
+ final int fullBits = hasVarFont()
+ ? (1 << allParameterCount) - 1 : (1 << (allParameterCount - 1)) - 1;
+ for (int bits = 1; bits <= fullBits; ++bits) {
Object[] param = new Object[allParameterCount];
for (int j = 0; j < allParameterCount; ++j) {
param[j] = new Boolean((bits & (1 << j)) != 0);
@@ -167,6 +171,12 @@
return allParams;
}
+ private static boolean hasVarFont() {
+ final TextPaint copied = new TextPaint((new TextView(getContext())).getPaint());
+ return copied.setFontVariationSettings("'wght' 400")
+ && copied.setFontVariationSettings("'wdth' 100");
+ }
+
@SmallTest
@Test
public void setText() {
diff --git a/tests/tests/widget/src/android/widget/cts/ToolbarTest.java b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
index ff4da10..8a70859 100644
--- a/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
@@ -287,6 +287,41 @@
}
@Test
+ public void testCollapseConfiguration() throws Throwable {
+ // Inflate menu and expand action view to display collapse button
+ WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
+ () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search));
+ final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search);
+ mActivityRule.runOnUiThread(searchMenuItem::expandActionView);
+ mInstrumentation.waitForIdleSync();
+
+ WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
+ () -> mMainToolbar.setCollapseIcon(R.drawable.icon_green));
+ Drawable toolbarCollapseIcon = mMainToolbar.getCollapseIcon();
+ TestUtils.assertAllPixelsOfColor("Collapse icon is green", toolbarCollapseIcon,
+ toolbarCollapseIcon.getIntrinsicWidth(),
+ toolbarCollapseIcon.getIntrinsicHeight(),
+ true, Color.GREEN, 1, false);
+
+ WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
+ () -> mMainToolbar.setCollapseIcon(mActivity.getDrawable(R.drawable.icon_blue)));
+ toolbarCollapseIcon = mMainToolbar.getCollapseIcon();
+ TestUtils.assertAllPixelsOfColor("Collapse icon is blue", toolbarCollapseIcon,
+ toolbarCollapseIcon.getIntrinsicWidth(),
+ toolbarCollapseIcon.getIntrinsicHeight(),
+ true, Color.BLUE, 1, false);
+
+ mActivityRule.runOnUiThread(
+ () -> mMainToolbar.setCollapseContentDescription(R.string.toolbar_collapse));
+ assertEquals(mActivity.getResources().getString(R.string.toolbar_collapse),
+ mMainToolbar.getCollapseContentDescription());
+
+ mActivityRule.runOnUiThread(
+ () -> mMainToolbar.setCollapseContentDescription("Collapse legend"));
+ assertEquals("Collapse legend", mMainToolbar.getCollapseContentDescription());
+ }
+
+ @Test
public void testLogoConfiguration() throws Throwable {
WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
() -> mMainToolbar.setLogo(R.drawable.icon_yellow));